summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autobuild.xml66
-rw-r--r--indra/cmake/Atmosphere.cmake5
-rw-r--r--indra/cmake/LLRender.cmake1
-rw-r--r--indra/llappearance/llwearabletype.cpp8
-rw-r--r--indra/llappearance/llwearabletype.h13
-rw-r--r--indra/llcommon/indra_constants.cpp1
-rw-r--r--indra/llcommon/indra_constants.h1
-rw-r--r--indra/llcommon/llassettype.cpp70
-rw-r--r--indra/llcommon/llassettype.h19
-rw-r--r--indra/llcommon/lllivefile.cpp1
-rw-r--r--indra/llcommon/llmemory.cpp6
-rw-r--r--indra/llcommon/llsd.cpp26
-rw-r--r--indra/llcommon/llsd.h5
-rw-r--r--indra/llcommon/llsdserialize.cpp10
-rw-r--r--indra/llcommon/llsdserialize.h2
-rw-r--r--indra/llcommon/llsdutil.cpp275
-rw-r--r--indra/llcommon/llsdutil.h96
-rw-r--r--indra/llcommon/llunittype.h37
-rw-r--r--indra/llcommon/lluuid.h20
-rw-r--r--indra/llcorehttp/tests/test_refcounted.hpp5
-rw-r--r--indra/llinventory/CMakeLists.txt11
-rw-r--r--indra/llinventory/llfoldertype.cpp4
-rw-r--r--indra/llinventory/llfoldertype.h2
-rw-r--r--indra/llinventory/llinventorydefines.h7
-rw-r--r--indra/llinventory/llinventorysettings.cpp116
-rw-r--r--indra/llinventory/llinventorysettings.h56
-rw-r--r--indra/llinventory/llinventorytype.cpp15
-rw-r--r--indra/llinventory/llinventorytype.h10
-rw-r--r--indra/llinventory/llinvtranslationbrdg.h41
-rw-r--r--indra/llinventory/llparcel.cpp3
-rw-r--r--indra/llinventory/llparcel.h16
-rw-r--r--indra/llinventory/llsettingsbase.cpp691
-rw-r--r--indra/llinventory/llsettingsbase.h507
-rw-r--r--indra/llinventory/llsettingsdaycycle.cpp895
-rw-r--r--indra/llinventory/llsettingsdaycycle.h156
-rw-r--r--indra/llinventory/llsettingssky.cpp1460
-rw-r--r--indra/llinventory/llsettingssky.h321
-rw-r--r--indra/llinventory/llsettingswater.cpp269
-rw-r--r--indra/llinventory/llsettingswater.h246
-rw-r--r--indra/llmath/CMakeLists.txt1
-rw-r--r--indra/llmath/llquaternion.cpp24
-rw-r--r--indra/llmath/llquaternion.h28
-rw-r--r--indra/llmath/llvolume.cpp8
-rw-r--r--indra/llmath/m3math.cpp24
-rw-r--r--indra/llmath/m3math.h4
-rw-r--r--indra/llmath/m4math.cpp27
-rw-r--r--indra/llmath/m4math.h6
-rw-r--r--indra/llmath/tests/m3math_test.cpp2
-rw-r--r--indra/llmath/v2math.cpp2
-rw-r--r--indra/llmath/v2math.h7
-rw-r--r--indra/llmath/v3color.h17
-rw-r--r--indra/llmath/v3colorutil.h115
-rw-r--r--indra/llmath/v4color.h11
-rw-r--r--indra/llmath/v4math.h34
-rw-r--r--indra/llmessage/llassetstorage.cpp54
-rw-r--r--indra/llmessage/llassetstorage.h31
-rw-r--r--indra/llmessage/llcircuit.cpp6
-rw-r--r--indra/llmessage/llregionflags.h3
-rw-r--r--indra/llmessage/message_prehash.cpp4
-rw-r--r--indra/llmessage/message_prehash.h3
-rw-r--r--indra/llplugin/llpluginprocesschild.cpp2
-rw-r--r--indra/llrender/CMakeLists.txt12
-rw-r--r--indra/llrender/llatmosphere.cpp349
-rw-r--r--indra/llrender/llatmosphere.h118
-rw-r--r--indra/llrender/llgl.cpp4
-rw-r--r--indra/llrender/llglslshader.cpp35
-rw-r--r--indra/llrender/llglslshader.h5
-rw-r--r--indra/llrender/llgltexture.cpp198
-rw-r--r--indra/llrender/llgltexture.h10
-rw-r--r--indra/llrender/llimagegl.cpp39
-rw-r--r--indra/llrender/llimagegl.h9
-rw-r--r--indra/llrender/llrender.cpp126
-rw-r--r--indra/llrender/llrender.h36
-rw-r--r--indra/llrender/llshadermgr.cpp86
-rw-r--r--indra/llrender/llshadermgr.h20
-rw-r--r--indra/llrender/lltexture.cpp12
-rw-r--r--indra/llrender/lltexture.h22
-rw-r--r--indra/llui/CMakeLists.txt4
-rw-r--r--indra/llui/llfolderview.cpp25
-rw-r--r--indra/llui/llfolderview.h8
-rw-r--r--indra/llui/llmultislider.cpp311
-rw-r--r--indra/llui/llmultislider.h21
-rw-r--r--indra/llui/llmultisliderctrl.cpp24
-rw-r--r--indra/llui/llmultisliderctrl.h21
-rw-r--r--indra/llui/llslider.cpp5
-rw-r--r--indra/llui/llui.h5
-rw-r--r--indra/llui/llvirtualtrackball.cpp480
-rw-r--r--indra/llui/llvirtualtrackball.h160
-rw-r--r--indra/llui/llxyvector.cpp306
-rw-r--r--indra/llui/llxyvector.h118
-rw-r--r--indra/newview/CMakeLists.txt47
-rw-r--r--indra/newview/app_settings/settings.xml57
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl329
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl24
-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.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl89
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl342
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonV.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl60
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl (renamed from indra/newview/llfloaterdeleteenvpreset.h)57
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl338
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl8
-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.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl68
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/srgbF.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl)16
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterF.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl13
-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/objects/fullbrightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl55
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonF.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonV.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl336
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl60
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl130
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl109
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl190
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl314
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/skyF.glsl83
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/skyV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl189
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl313
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl247
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl308
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl41
-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.glsl148
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl133
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/transportF.glsl74
-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/llagent.cpp15
-rw-r--r--indra/newview/llagent.h10
-rw-r--r--indra/newview/llagentwearables.cpp11
-rw-r--r--indra/newview/llappearancemgr.cpp3
-rw-r--r--indra/newview/llappviewer.cpp10
-rw-r--r--indra/newview/llappviewer.h2
-rw-r--r--indra/newview/lldaycyclemanager.cpp3
-rw-r--r--indra/newview/lldaycyclemanager.h5
-rw-r--r--indra/newview/lldensityctrl.cpp225
-rw-r--r--indra/newview/lldensityctrl.h104
-rw-r--r--indra/newview/lldrawpoolalpha.cpp51
-rw-r--r--indra/newview/lldrawpoolavatar.cpp133
-rw-r--r--indra/newview/lldrawpoolbump.cpp17
-rw-r--r--indra/newview/lldrawpoolground.cpp2
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp9
-rw-r--r--indra/newview/lldrawpoolsimple.cpp155
-rw-r--r--indra/newview/lldrawpoolsky.cpp2
-rw-r--r--indra/newview/lldrawpoolwater.cpp282
-rw-r--r--indra/newview/lldrawpoolwater.h17
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp484
-rw-r--r--indra/newview/lldrawpoolwlsky.h32
-rw-r--r--indra/newview/llenvadapters.cpp67
-rw-r--r--indra/newview/llenvadapters.h459
-rw-r--r--indra/newview/llenvironment.cpp1884
-rw-r--r--indra/newview/llenvironment.h402
-rw-r--r--indra/newview/llenvmanager.cpp721
-rw-r--r--indra/newview/llenvmanager.h349
-rw-r--r--indra/newview/llestateinfomodel.cpp4
-rw-r--r--indra/newview/llestateinfomodel.h2
-rw-r--r--indra/newview/llface.cpp7
-rw-r--r--indra/newview/llface.h1
-rw-r--r--indra/newview/llfloaterbulkpermission.cpp11
-rw-r--r--indra/newview/llfloaterbulkpermission.h1
-rw-r--r--indra/newview/llfloaterbuy.cpp2
-rw-r--r--indra/newview/llfloaterbuycontents.cpp2
-rw-r--r--indra/newview/llfloaterdeleteenvpreset.cpp285
-rw-r--r--indra/newview/llfloatereditdaycycle.cpp108
-rw-r--r--indra/newview/llfloatereditdaycycle.h26
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp1594
-rw-r--r--indra/newview/llfloatereditextdaycycle.h228
-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/llfloaterenvironmentsettings.cpp282
-rw-r--r--indra/newview/llfloaterenvironmentsettings.h71
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp751
-rw-r--r--indra/newview/llfloaterfixedenvironment.h199
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llfloaterland.cpp162
-rw-r--r--indra/newview/llfloaterland.h5
-rw-r--r--indra/newview/llfloatermyenvironment.cpp494
-rw-r--r--indra/newview/llfloatermyenvironment.h132
-rw-r--r--indra/newview/llfloaternamedesc.cpp4
-rw-r--r--indra/newview/llfloaterperms.cpp3
-rw-r--r--indra/newview/llfloaterperms.h1
-rw-r--r--indra/newview/llfloaterpreference.cpp23
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterregioninfo.cpp794
-rw-r--r--indra/newview/llfloaterregioninfo.h70
-rw-r--r--indra/newview/llflyoutcombobtn.cpp156
-rw-r--r--indra/newview/llflyoutcombobtn.h75
-rw-r--r--indra/newview/llfolderviewmodelinventory.h5
-rw-r--r--indra/newview/llfriendcard.cpp2
-rw-r--r--indra/newview/llhudtext.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp213
-rw-r--r--indra/newview/llinventorybridge.h27
-rw-r--r--indra/newview/llinventoryfilter.cpp28
-rw-r--r--indra/newview/llinventoryfilter.h31
-rw-r--r--indra/newview/llinventoryfunctions.cpp25
-rw-r--r--indra/newview/llinventoryicon.cpp18
-rw-r--r--indra/newview/llinventoryicon.h1
-rw-r--r--indra/newview/llinventorymodel.cpp3
-rw-r--r--indra/newview/llinventorypanel.cpp14
-rw-r--r--indra/newview/llinventorypanel.h12
-rw-r--r--indra/newview/lljoystickbutton.cpp237
-rw-r--r--indra/newview/lljoystickbutton.h44
-rw-r--r--indra/newview/lllandmarkactions.cpp2
-rw-r--r--indra/newview/lllegacyatmospherics.cpp664
-rw-r--r--indra/newview/lllegacyatmospherics.h280
-rw-r--r--indra/newview/lllocationinputctrl.cpp1
-rw-r--r--indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp1
-rw-r--r--indra/newview/llmeshrepository.cpp2
-rw-r--r--indra/newview/lloutfitgallery.cpp3
-rw-r--r--indra/newview/llpaneleditsky.cpp747
-rw-r--r--indra/newview/llpaneleditsky.h165
-rw-r--r--indra/newview/llpaneleditwater.cpp243
-rw-r--r--indra/newview/llpaneleditwater.h98
-rw-r--r--indra/newview/llpanelenvironment.cpp777
-rw-r--r--indra/newview/llpanelenvironment.h178
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanelmaininventory.cpp20
-rw-r--r--indra/newview/llpanelmaininventory.h1
-rw-r--r--indra/newview/llpanelobjectinventory.cpp36
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp6
-rw-r--r--indra/newview/llpanelsnapshotpostcard.cpp6
-rw-r--r--indra/newview/llpreviewgesture.cpp10
-rw-r--r--indra/newview/llpreviewnotecard.cpp13
-rw-r--r--indra/newview/llpreviewscript.cpp15
-rw-r--r--indra/newview/llsettingspicker.cpp412
-rw-r--r--indra/newview/llsettingspicker.h126
-rw-r--r--indra/newview/llsettingsvo.cpp1338
-rw-r--r--indra/newview/llsettingsvo.h182
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp24
-rw-r--r--indra/newview/llsky.cpp240
-rw-r--r--indra/newview/llsky.h53
-rw-r--r--indra/newview/llstartup.cpp29
-rw-r--r--indra/newview/lltooldraganddrop.cpp4
-rw-r--r--indra/newview/lltoolgun.cpp11
-rw-r--r--indra/newview/lltracker.cpp4
-rw-r--r--indra/newview/llviewerassetstorage.h6
-rw-r--r--indra/newview/llviewerassettype.cpp1
-rw-r--r--indra/newview/llviewerassetupload.cpp10
-rw-r--r--indra/newview/llviewerassetupload.h6
-rw-r--r--indra/newview/llviewercamera.cpp25
-rw-r--r--indra/newview/llviewercamera.h8
-rw-r--r--indra/newview/llviewercontrol.cpp12
-rw-r--r--indra/newview/llviewerdisplay.cpp35
-rw-r--r--indra/newview/llviewerfloaterreg.cpp21
-rw-r--r--indra/newview/llviewerfoldertype.cpp3
-rw-r--r--indra/newview/llviewerinventory.cpp75
-rw-r--r--indra/newview/llviewerinventory.h25
-rw-r--r--indra/newview/llviewermenu.cpp202
-rw-r--r--indra/newview/llviewermenufile.cpp8
-rw-r--r--indra/newview/llviewermenufile.h2
-rw-r--r--indra/newview/llviewermessage.cpp12
-rw-r--r--indra/newview/llviewernetwork.cpp34
-rw-r--r--indra/newview/llvieweroctree.cpp2
-rw-r--r--indra/newview/llviewerparcelmgr.cpp73
-rw-r--r--indra/newview/llviewerparcelmgr.h2
-rw-r--r--indra/newview/llviewerregion.cpp6
-rw-r--r--indra/newview/llviewershadermgr.cpp335
-rw-r--r--indra/newview/llviewershadermgr.h24
-rw-r--r--indra/newview/llviewertexteditor.cpp105
-rw-r--r--indra/newview/llviewertexteditor.h1
-rw-r--r--indra/newview/llviewertexture.cpp32
-rw-r--r--indra/newview/llviewertexture.h4
-rw-r--r--indra/newview/llviewerwindow.cpp4
-rw-r--r--indra/newview/llvoground.cpp2
-rw-r--r--indra/newview/llvosky.cpp2128
-rw-r--r--indra/newview/llvosky.h494
-rw-r--r--indra/newview/llvovolume.cpp2
-rw-r--r--indra/newview/llvowlsky.cpp321
-rw-r--r--indra/newview/llvowlsky.h6
-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/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.cpp418
-rw-r--r--indra/newview/llwlparamset.h246
-rw-r--r--indra/newview/pipeline.cpp398
-rw-r--r--indra/newview/pipeline.h38
-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/textures.xml20
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.pngbin475 -> 429 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_moon_back.pngbin0 -> 859 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_moon_front.pngbin0 -> 1100 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/xui/da/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/de/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/de/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml14
-rw-r--r--indra/newview/skins/default/xui/en/floater_bulk_perms.xml15
-rw-r--r--indra/newview/skins/default/xui/en/floater_delete_env_preset.xml59
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml582
-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_inventory_view_finder.xml29
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_environments.xml174
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml61
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml16
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_picker.xml116
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml404
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml62
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml525
-rw-r--r--indra/newview/skins/default/xui/en/menu_save_settings.xml68
-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_viewer.xml67
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml134
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml1048
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_environment.xml504
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml253
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml247
-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.xml271
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_water.xml370
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml24
-rw-r--r--indra/newview/skins/default/xui/en/widgets/density_ctrl.xml164
-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/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_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/es/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/it/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/it/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/pl/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml3
-rw-r--r--indra/newview/tests/llviewernetwork_test.cpp4
-rw-r--r--indra/test/llsdmessagebuilder_tut.cpp2
-rw-r--r--indra/test/llsdmessagereader_tut.cpp2
-rw-r--r--indra/test/llsdutil_tut.cpp45
-rw-r--r--indra/test/lltemplatemessagebuilder_tut.cpp5
-rwxr-xr-xscripts/messages/message_template.msg5
-rwxr-xr-xscripts/messages/message_template.msg.sha12
430 files changed, 33018 insertions, 15904 deletions
diff --git a/autobuild.xml b/autobuild.xml
index 3107d77548..6ab50ab183 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -45,6 +45,72 @@
<key>version</key>
<string>1.2.15</string>
</map>
+ <key>libatmosphere</key>
+ <map>
+ <key>copyright</key>
+ <string>Copyright © 2017 Eric Bruneton.</string>
+ <key>description</key>
+ <string>Precomputed multiple atmospheric scattering library.</string>
+ <key>license</key>
+ <string>BSD</string>
+ <key>license_file</key>
+ <string>LICENSES/libatmosphere.txt</string>
+ <key>name</key>
+ <string>libatmosphere</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>bca20bcdf1a2c26b16e71fb2c1316cbe</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24187/188163/libatmosphere-1.0.0.100-darwin-519422.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin</string>
+ </map>
+ <key>darwin64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>9ce4c97f1eda8caa556573abd6e1ebd0</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24188/188166/libatmosphere-1.0.0.100-darwin64-519422.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin64</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>6a61502ab1cca316f85310ded8bf9b9a</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24190/188181/libatmosphere-1.0.0.100-windows-519422.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ <key>windows64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>496410cb43e03ddf1777cd295c2d5dba</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24189/188175/libatmosphere-1.0.0.100-windows64-519422.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows64</string>
+ </map>
+ </map>
+ <key>version</key>
+ <string>1.0.0.513060</string>
+ </map>
<key>apr_suite</key>
<map>
<key>copyright</key>
diff --git a/indra/cmake/Atmosphere.cmake b/indra/cmake/Atmosphere.cmake
new file mode 100644
index 0000000000..9c14df2a11
--- /dev/null
+++ b/indra/cmake/Atmosphere.cmake
@@ -0,0 +1,5 @@
+# -*- cmake -*-
+include(Prebuilt)
+use_prebuilt_binary(libatmosphere)
+set(LIBATMOSPHERE_LIBRARIES atmosphere)
+set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere)
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
index 868922451f..0940d1de63 100644
--- a/indra/cmake/LLRender.cmake
+++ b/indra/cmake/LLRender.cmake
@@ -3,6 +3,7 @@
include(Variables)
include(FreeType)
include(GLH)
+include(Atmosphere)
set(LLRENDER_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llrender
diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
index cd602b43b4..4daf34eca6 100644
--- a/indra/llappearance/llwearabletype.cpp
+++ b/indra/llappearance/llwearabletype.cpp
@@ -29,17 +29,17 @@
#include "llinventorytype.h"
#include "llinventorydefines.h"
-static LLTranslationBridge* sTrans = NULL;
+static LLTranslationBridge::ptr_t sTrans = NULL;
// static
-void LLWearableType::initClass(LLTranslationBridge* trans)
+void LLWearableType::initClass(LLTranslationBridge::ptr_t &trans)
{
sTrans = trans;
}
void LLWearableType::cleanupClass()
{
- delete sTrans;
+ sTrans.reset();
}
struct WearableEntry : public LLDictionaryEntry
@@ -172,6 +172,6 @@ BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)
// static
LLWearableType::EType LLWearableType::inventoryFlagsToWearableType(U32 flags)
{
- return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
+ return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
}
diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h
index 519d5b92a2..74eb904c8d 100644
--- a/indra/llappearance/llwearabletype.h
+++ b/indra/llappearance/llwearabletype.h
@@ -31,16 +31,7 @@
#include "lldictionary.h"
#include "llinventorytype.h"
#include "llsingleton.h"
-
-class LLTranslationBridge
-{
-public:
- // clang needs this to be happy
- virtual ~LLTranslationBridge() {}
-
- virtual std::string getString(const std::string &xml_desc) = 0;
-};
-
+#include "llinvtranslationbrdg.h"
class LLWearableType
{
@@ -69,7 +60,7 @@ public:
WT_NONE = -1,
};
- static void initClass(LLTranslationBridge* trans); // initializes static members
+ static void initClass(LLTranslationBridge::ptr_t &trans); // initializes static members
static void cleanupClass(); // initializes static members
static const std::string& getTypeName(EType type);
diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp
index 7ea42a3fc0..601eb45570 100644
--- a/indra/llcommon/indra_constants.cpp
+++ b/indra/llcommon/indra_constants.cpp
@@ -64,7 +64,6 @@ const LLUUID IMG_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEW
const LLUUID IMG_ALPHA_GRAD_2D ("38b86f85-2575-52a9-a531-23108d8da837"); // VIEWER
const LLUUID IMG_TRANSPARENT ("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); // VIEWER
-const LLUUID IMG_BLOOM1 ("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef"); // VIEWER
const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER
const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER
const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); // VIEWER
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index a00a82aff0..010a190181 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -201,7 +201,6 @@ LL_COMMON_API extern const LLUUID IMG_ALPHA_GRAD;
LL_COMMON_API extern const LLUUID IMG_ALPHA_GRAD_2D;
LL_COMMON_API extern const LLUUID IMG_TRANSPARENT;
-LL_COMMON_API extern const LLUUID IMG_BLOOM1;
LL_COMMON_API extern const LLUUID TERRAIN_DIRT_DETAIL;
LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL;
LL_COMMON_API extern const LLUUID TERRAIN_MOUNTAIN_DETAIL;
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 7e5a157cdf..d455805aea 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -70,36 +70,40 @@ LLAssetDictionary::LLAssetDictionary()
{
// DESCRIPTION TYPE NAME HUMAN NAME CAN LINK? CAN FETCH? CAN KNOW?
// |--------------------|-----------|-------------------|-----------|-----------|---------|
- addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true));
- addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true));
- addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false));
- addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true));
- addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false));
- addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true));
- addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false));
- addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true));
- addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false));
- addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false));
- addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false));
- addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false));
- addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true));
- addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false));
- addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false));
- addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false));
- addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true));
- addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true));
- addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false));
-
- addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true));
- addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
- addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
- addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
- addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
+ addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true));
+ addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true));
+ addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false));
+ addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true));
+ addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false));
+ addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true));
+ addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false));
+ addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true));
+ addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false));
+ addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false));
+ addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false));
+ addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false));
+ addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true));
+ addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false));
+ addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false));
+ addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false));
+ addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true));
+ addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true));
+ addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false));
+
+ addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true));
+ addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
+ addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
+ addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
+ addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
+ addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, false));
+
addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
- addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
+ addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};
+const std::string LLAssetType::BADLOOKUP("llassettype_bad_lookup");
+
// static
LLAssetType::EType LLAssetType::getType(const std::string& desc_name)
{
@@ -118,7 +122,7 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type)
}
else
{
- return badLookup();
+ return BADLOOKUP;
}
}
@@ -133,7 +137,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type)
}
else
{
- return badLookup().c_str();
+ return BADLOOKUP.c_str();
}
}
@@ -171,7 +175,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
}
else
{
- return badLookup().c_str();
+ return BADLOOKUP.c_str();
}
}
@@ -222,14 +226,6 @@ bool LLAssetType::lookupIsLinkType(EType asset_type)
}
// static
-const std::string &LLAssetType::badLookup()
-{
- static const std::string sBadLookup = "llassettype_bad_lookup";
- return sBadLookup;
-
-}
-
-// static
bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type)
{
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 79ab3d7efe..652c548d59 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -116,10 +116,19 @@ public:
AT_PERSON = 45,
// A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
- AT_MESH = 49,
- // Mesh data in our proprietary SLM format
-
- AT_COUNT = 50,
+ AT_MESH = 49,
+ // Mesh data in our proprietary SLM format
+
+ AT_RESERVED_1 = 50,
+ AT_RESERVED_2 = 51,
+ AT_RESERVED_3 = 52,
+ AT_RESERVED_4 = 53,
+ AT_RESERVED_5 = 54,
+ AT_RESERVED_6 = 55,
+
+ AT_SETTINGS = 56, // Collection of settings
+
+ AT_COUNT = 57,
// +*********************************************************+
// | TO ADD AN ELEMENT TO THIS ENUM: |
@@ -153,7 +162,7 @@ public:
static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
- static const std::string& badLookup(); // error string when a lookup fails
+ static const std::string BADLOOKUP;
protected:
LLAssetType() {}
diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp
index ea485c2d86..4b73ff691a 100644
--- a/indra/llcommon/lllivefile.cpp
+++ b/indra/llcommon/lllivefile.cpp
@@ -150,6 +150,7 @@ bool LLLiveFile::checkAndReload()
}
else
{
+ LL_WARNS() << "Failed to load live file " << filename() << LL_ENDL;
changed = false;
}
}
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index b3debf3550..1884d6f04f 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -77,7 +77,7 @@ void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
//static
void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure)
{
- sMaxHeapSizeInKB = max_heap_size;
+ sMaxHeapSizeInKB = U32Kilobytes::convert(max_heap_size);
sEnableMemoryFailurePrevention = prevent_heap_failure ;
}
@@ -93,9 +93,9 @@ void LLMemory::updateMemoryInfo()
return ;
}
- sAllocatedMemInKB = U64Bytes(counters.WorkingSetSize) ;
+ sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
sample(sAllocatedMem, sAllocatedMemInKB);
- sAllocatedPageSizeInKB = U64Bytes(counters.PagefileUsage) ;
+ sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
sample(sVirtualMem, sAllocatedPageSizeInKB);
U32Kilobytes avail_phys, avail_virtual;
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 57aa7d9c07..57b746889d 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -132,6 +132,7 @@ public:
virtual bool has(const String&) const { return false; }
virtual LLSD get(const String&) const { return LLSD(); }
+ virtual LLSD getKeys() const { return LLSD::emptyArray(); }
virtual void erase(const String&) { }
virtual const LLSD& ref(const String&) const{ return undef(); }
@@ -380,7 +381,8 @@ namespace
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
virtual LLSD get(const LLSD::String&) const;
- void insert(const LLSD::String& k, const LLSD& v);
+ virtual LLSD getKeys() const;
+ void insert(const LLSD::String& k, const LLSD& v);
virtual void erase(const LLSD::String&);
LLSD& ref(const LLSD::String&);
virtual const LLSD& ref(const LLSD::String&) const;
@@ -421,7 +423,19 @@ namespace
DataMap::const_iterator i = mData.find(k);
return (i != mData.end()) ? i->second : LLSD();
}
-
+
+ LLSD ImplMap::getKeys() const
+ {
+ LLSD keys = LLSD::emptyArray();
+ DataMap::const_iterator iter = mData.begin();
+ while (iter != mData.end())
+ {
+ keys.append((*iter).first);
+ iter++;
+ }
+ return keys;
+ }
+
void ImplMap::insert(const LLSD::String& k, const LLSD& v)
{
mData.insert(DataMap::value_type(k, v));
@@ -502,7 +516,7 @@ namespace
virtual LLSD get(LLSD::Integer) const;
void set(LLSD::Integer, const LLSD&);
void insert(LLSD::Integer, const LLSD&);
- void append(const LLSD&);
+ LLSD& append(const LLSD&);
virtual void erase(LLSD::Integer);
LLSD& ref(LLSD::Integer);
virtual const LLSD& ref(LLSD::Integer) const;
@@ -570,9 +584,10 @@ namespace
mData.insert(mData.begin() + index, v);
}
- void ImplArray::append(const LLSD& v)
+ LLSD& ImplArray::append(const LLSD& v)
{
mData.push_back(v);
+ return mData.back();
}
void ImplArray::erase(LLSD::Integer i)
@@ -862,6 +877,7 @@ LLSD LLSD::emptyMap()
bool LLSD::has(const String& k) const { return safe(impl).has(k); }
LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
+LLSD LLSD::getKeys() const { return safe(impl).getKeys(); }
void LLSD::insert(const String& k, const LLSD& v) { makeMap(impl).insert(k, v); }
LLSD& LLSD::with(const String& k, const LLSD& v)
@@ -895,7 +911,7 @@ LLSD& LLSD::with(Integer i, const LLSD& v)
makeArray(impl).insert(i, v);
return *this;
}
-void LLSD::append(const LLSD& v) { makeArray(impl).append(v); }
+LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); }
void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
LLSD& LLSD::operator[](Integer i)
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 7b9b1285f5..5b6d5545af 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -79,7 +79,7 @@
an LLSD array).
An array is a sequence of zero or more LLSD values.
-
+
Thread Safety
In general, these LLSD classes offer *less* safety than STL container
@@ -284,6 +284,7 @@ public:
bool has(const String&) const;
LLSD get(const String&) const;
+ LLSD getKeys() const; // Return an LLSD array with keys as strings
void insert(const String&, const LLSD&);
void erase(const String&);
LLSD& with(const String&, const LLSD&);
@@ -301,7 +302,7 @@ public:
LLSD get(Integer) const;
void set(Integer, const LLSD&);
void insert(Integer, const LLSD&);
- void append(const LLSD&);
+ LLSD& append(const LLSD&);
void erase(Integer);
LLSD& with(Integer, const LLSD&);
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 1aaff5628f..c3fb4ebc2c 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -55,6 +55,7 @@ static const S32 UNZIP_LLSD_MAX_DEPTH = 96;
static const char LEGACY_NON_HEADER[] = "<llsd>";
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
const std::string LLSD_XML_HEADER("LLSD/XML");
+const std::string LLSD_NOTATION_HEADER("llsd/notation");
//used to deflate a gzipped asset (currently used for navmeshes)
#define windowBits 15
@@ -81,6 +82,11 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize
f = new LLSDXMLFormatter;
break;
+ case LLSD_NOTATION:
+ str << "<? " << LLSD_NOTATION_HEADER << " ?>\n";
+ f = new LLSDNotationFormatter;
+ break;
+
default:
LL_WARNS() << "serialize request for unknown ELLSD_Serialize" << LL_ENDL;
}
@@ -168,6 +174,10 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
{
p = new LLSDXMLParser;
}
+ else if (header == LLSD_NOTATION_HEADER)
+ {
+ p = new LLSDNotationParser;
+ }
else
{
LL_WARNS() << "deserialize request for unknown ELLSD_Serialize" << LL_ENDL;
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 8165410e80..fe0f4443ef 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -706,7 +706,7 @@ class LL_COMMON_API LLSDSerialize
public:
enum ELLSD_Serialize
{
- LLSD_BINARY, LLSD_XML
+ LLSD_BINARY, LLSD_XML, LLSD_NOTATION
};
/**
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index 9d00395c0a..6a23c443a0 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -322,6 +322,180 @@ BOOL compare_llsd_with_template(
return TRUE;
}
+// filter_llsd_with_template() is a direct clone (copy-n-paste) of
+// compare_llsd_with_template with the following differences:
+// (1) bool vs BOOL return types
+// (2) A map with the key value "*" is a special value and maps any key in the
+// test llsd that doesn't have an explicitly matching key in the template.
+// (3) The element of an array with exactly one element is taken as a template
+// for *all* the elements of the test array. If the template array is of
+// different size, compare_llsd_with_template() semantics apply.
+bool filter_llsd_with_template(
+ const LLSD & llsd_to_test,
+ const LLSD & template_llsd,
+ LLSD & resultant_llsd)
+{
+ if (llsd_to_test.isUndefined() && template_llsd.isDefined())
+ {
+ resultant_llsd = template_llsd;
+ return true;
+ }
+ else if (llsd_to_test.type() != template_llsd.type())
+ {
+ resultant_llsd = LLSD();
+ return false;
+ }
+
+ if (llsd_to_test.isArray())
+ {
+ //they are both arrays
+ //we loop over all the items in the template
+ //verifying that the to_test has a subset (in the same order)
+ //any shortcoming in the testing_llsd are just taken
+ //to be the rest of the template
+ LLSD data;
+ LLSD::array_const_iterator test_iter;
+ LLSD::array_const_iterator template_iter;
+
+ resultant_llsd = LLSD::emptyArray();
+ test_iter = llsd_to_test.beginArray();
+
+ if (1 == template_llsd.size())
+ {
+ // If the template has a single item, treat it as
+ // the template for *all* items in the test LLSD.
+ template_iter = template_llsd.beginArray();
+
+ for (; test_iter != llsd_to_test.endArray(); ++test_iter)
+ {
+ if (! filter_llsd_with_template(*test_iter, *template_iter, data))
+ {
+ resultant_llsd = LLSD();
+ return false;
+ }
+ else
+ {
+ resultant_llsd.append(data);
+ }
+ }
+ }
+ else
+ {
+ // Traditional compare_llsd_with_template matching
+
+ for (template_iter = template_llsd.beginArray();
+ template_iter != template_llsd.endArray() &&
+ test_iter != llsd_to_test.endArray();
+ ++template_iter, ++test_iter)
+ {
+ if (! filter_llsd_with_template(*test_iter, *template_iter, data))
+ {
+ resultant_llsd = LLSD();
+ return false;
+ }
+ else
+ {
+ resultant_llsd.append(data);
+ }
+ }
+
+ //so either the test or the template ended
+ //we do another loop now to the end of the template
+ //grabbing the default values
+ for (;
+ template_iter != template_llsd.endArray();
+ ++template_iter)
+ {
+ resultant_llsd.append(*template_iter);
+ }
+ }
+ }
+ else if (llsd_to_test.isMap())
+ {
+ resultant_llsd = LLSD::emptyMap();
+
+ //now we loop over the keys of the two maps
+ //any excess is taken from the template
+ //excess is ignored in the test
+
+ // Special tag for wildcarded LLSD map key templates
+ const LLSD::String wildcard_tag("*");
+
+ const bool template_has_wildcard = template_llsd.has(wildcard_tag);
+ LLSD wildcard_value;
+ LLSD value;
+
+ const LLSD::map_const_iterator template_iter_end(template_llsd.endMap());
+ for (LLSD::map_const_iterator template_iter(template_llsd.beginMap());
+ template_iter_end != template_iter;
+ ++template_iter)
+ {
+ if (wildcard_tag == template_iter->first)
+ {
+ wildcard_value = template_iter->second;
+ }
+ else if (llsd_to_test.has(template_iter->first))
+ {
+ //the test LLSD has the same key
+ if (! filter_llsd_with_template(llsd_to_test[template_iter->first],
+ template_iter->second,
+ value))
+ {
+ resultant_llsd = LLSD();
+ return false;
+ }
+ else
+ {
+ resultant_llsd[template_iter->first] = value;
+ }
+ }
+ else if (! template_has_wildcard)
+ {
+ // test llsd doesn't have it...take the
+ // template as default value
+ resultant_llsd[template_iter->first] = template_iter->second;
+ }
+ }
+ if (template_has_wildcard)
+ {
+ LLSD sub_value;
+ LLSD::map_const_iterator test_iter;
+
+ for (test_iter = llsd_to_test.beginMap();
+ test_iter != llsd_to_test.endMap();
+ ++test_iter)
+ {
+ if (resultant_llsd.has(test_iter->first))
+ {
+ // Final value has test key, assume more specific
+ // template matched and we shouldn't modify it again.
+ continue;
+ }
+ else if (! filter_llsd_with_template(test_iter->second,
+ wildcard_value,
+ sub_value))
+ {
+ // Test value doesn't match wildcarded template
+ resultant_llsd = LLSD();
+ return false;
+ }
+ else
+ {
+ // Test value matches template, add the actuals.
+ resultant_llsd[test_iter->first] = sub_value;
+ }
+ }
+ }
+ }
+ else
+ {
+ //of same type...take the test llsd's value
+ resultant_llsd = llsd_to_test;
+ }
+
+ return true;
+}
+
/*****************************************************************************
* Helpers for llsd_matches()
*****************************************************************************/
@@ -681,3 +855,104 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
return false; // pacify the compiler
}
}
+
+// Construct a deep partial clone of of an LLSD object. primitive types share
+// references, however maps, arrays and binary objects are duplicated. An optional
+// filter may be include to exclude/include keys in a map.
+LLSD llsd_clone(LLSD value, LLSD filter)
+{
+ LLSD clone;
+ bool has_filter(filter.isMap());
+
+ switch (value.type())
+ {
+ case LLSD::TypeMap:
+ clone = LLSD::emptyMap();
+ for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm)
+ {
+ if (has_filter)
+ {
+ if (filter.has((*itm).first))
+ {
+ if (!filter[(*itm).first].asBoolean())
+ continue;
+ }
+ else if (filter.has("*"))
+ {
+ if (!filter["*"].asBoolean())
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ clone[(*itm).first] = llsd_clone((*itm).second, filter);
+ }
+ break;
+ case LLSD::TypeArray:
+ clone = LLSD::emptyArray();
+ for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+ {
+ clone.append(llsd_clone(*ita, filter));
+ }
+ break;
+
+ case LLSD::TypeBinary:
+ {
+ LLSD::Binary bin(value.asBinary().begin(), value.asBinary().end());
+ clone = LLSD::Binary(bin);
+ break;
+ }
+ default:
+ clone = value;
+ }
+
+ return clone;
+}
+
+LLSD llsd_shallow(LLSD value, LLSD filter)
+{
+ LLSD shallow;
+ bool has_filter(filter.isMap());
+
+ if (value.isMap())
+ {
+ shallow = LLSD::emptyMap();
+ for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm)
+ {
+ if (has_filter)
+ {
+ if (filter.has((*itm).first))
+ {
+ if (!filter[(*itm).first].asBoolean())
+ continue;
+ }
+ else if (filter.has("*"))
+ {
+ if (!filter["*"].asBoolean())
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ shallow[(*itm).first] = (*itm).second;
+ }
+ }
+ else if (value.isArray())
+ {
+ shallow = LLSD::emptyArray();
+ for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+ {
+ shallow.append(*ita);
+ }
+ }
+ else
+ {
+ return value;
+ }
+
+ return shallow;
+}
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 01ab6bcb8d..863be04c8a 100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
@@ -30,6 +30,7 @@
#define LL_LLSDUTIL_H
#include "llsd.h"
+#include <boost/functional/hash.hpp>
// U32
LL_COMMON_API LLSD ll_sd_from_U32(const U32);
@@ -70,6 +71,19 @@ LL_COMMON_API BOOL compare_llsd_with_template(
const LLSD& template_llsd,
LLSD& resultant_llsd);
+// filter_llsd_with_template() is a direct clone (copy-n-paste) of
+// compare_llsd_with_template with the following differences:
+// (1) bool vs BOOL return types
+// (2) A map with the key value "*" is a special value and maps any key in the
+// test llsd that doesn't have an explicitly matching key in the template.
+// (3) The element of an array with exactly one element is taken as a template
+// for *all* the elements of the test array. If the template array is of
+// different size, compare_llsd_with_template() semantics apply.
+bool filter_llsd_with_template(
+ const LLSD & llsd_to_test,
+ const LLSD & template_llsd,
+ LLSD & resultant_llsd);
+
/**
* Recursively determine whether a given LLSD data block "matches" another
* LLSD prototype. The returned string is empty() on success, non-empty() on
@@ -421,4 +435,86 @@ private:
} // namespace llsd
+
+// Creates a deep clone of an LLSD object. Maps, Arrays and binary objects
+// are duplicated, atomic primitives (Boolean, Integer, Real, etc) simply
+// use a shared reference.
+// Optionally a filter may be specified to control what is duplicated. The
+// map takes the form "keyname/boolean".
+// If the value is true the value will be duplicated otherwise it will be skipped
+// when encountered in a map. A key name of "*" can be specified as a wild card
+// and will specify the default behavior. If no wild card is given and the clone
+// encounters a name not in the filter, that value will be skipped.
+LLSD llsd_clone(LLSD value, LLSD filter = LLSD());
+
+// Creates a shallow copy of a map or array. If passed any other type of LLSD
+// object it simply returns that value. See llsd_clone for a description of
+// the filter parameter.
+LLSD llsd_shallow(LLSD value, LLSD filter = LLSD());
+
+
+// Specialization for generating a hash value from an LLSD block.
+template <>
+struct boost::hash<LLSD>
+{
+ typedef LLSD argument_type;
+ typedef std::size_t result_type;
+ result_type operator()(argument_type const& s) const
+ {
+ result_type seed(0);
+
+ LLSD::Type stype = s.type();
+ boost::hash_combine(seed, (S32)stype);
+
+ switch (stype)
+ {
+ case LLSD::TypeBoolean:
+ boost::hash_combine(seed, s.asBoolean());
+ break;
+ case LLSD::TypeInteger:
+ boost::hash_combine(seed, s.asInteger());
+ break;
+ case LLSD::TypeReal:
+ boost::hash_combine(seed, s.asReal());
+ break;
+ case LLSD::TypeURI:
+ case LLSD::TypeString:
+ boost::hash_combine(seed, s.asString());
+ break;
+ case LLSD::TypeUUID:
+ boost::hash_combine(seed, s.asUUID());
+ break;
+ case LLSD::TypeDate:
+ boost::hash_combine(seed, s.asDate().secondsSinceEpoch());
+ break;
+ case LLSD::TypeBinary:
+ {
+ const LLSD::Binary &b(s.asBinary());
+ boost::hash_range(seed, b.begin(), b.end());
+ break;
+ }
+ case LLSD::TypeMap:
+ {
+ for (LLSD::map_const_iterator itm = s.beginMap(); itm != s.endMap(); ++itm)
+ {
+ boost::hash_combine(seed, (*itm).first);
+ boost::hash_combine(seed, (*itm).second);
+ }
+ break;
+ }
+ case LLSD::TypeArray:
+ for (LLSD::array_const_iterator ita = s.beginArray(); ita != s.endArray(); ++ita)
+ {
+ boost::hash_combine(seed, (*ita));
+ }
+ break;
+ case LLSD::TypeUndefined:
+ default:
+ break;
+ }
+
+ return seed;
+ }
+};
+
#endif // LL_LLSDUTIL_H
diff --git a/indra/llcommon/llunittype.h b/indra/llcommon/llunittype.h
index ac8504ca61..81f244e422 100644
--- a/indra/llcommon/llunittype.h
+++ b/indra/llcommon/llunittype.h
@@ -132,23 +132,34 @@ struct LLUnit
return mValue;
}
- LL_FORCE_INLINE void value(storage_t value)
+ LL_FORCE_INLINE void value(const storage_t& value)
{
mValue = value;
}
template<typename NEW_UNITS>
- storage_t valueInUnits()
+ storage_t valueInUnits() const
{
return LLUnit<storage_t, NEW_UNITS>(*this).value();
}
template<typename NEW_UNITS>
- void valueInUnits(storage_t value)
+ void valueInUnits(const storage_t& value) const
{
*this = LLUnit<storage_t, NEW_UNITS>(value);
}
+ LL_FORCE_INLINE operator storage_t() const
+ {
+ return value();
+ }
+
+ /*LL_FORCE_INLINE self_t& operator= (storage_t v)
+ {
+ value(v);
+ return *this;
+ }*/
+
LL_FORCE_INLINE void operator += (self_t other)
{
mValue += convert(other).mValue;
@@ -159,60 +170,60 @@ struct LLUnit
mValue -= convert(other).mValue;
}
- LL_FORCE_INLINE void operator *= (storage_t multiplicand)
+ LL_FORCE_INLINE void operator *= (const storage_t& multiplicand)
{
mValue *= multiplicand;
}
- LL_FORCE_INLINE void operator *= (self_t multiplicand)
+ LL_FORCE_INLINE void operator *= (const self_t& multiplicand)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Multiplication of unit types not supported.");
}
- LL_FORCE_INLINE void operator /= (storage_t divisor)
+ LL_FORCE_INLINE void operator /= (const storage_t& divisor)
{
mValue /= divisor;
}
- void operator /= (self_t divisor)
+ void operator /= (const self_t& divisor)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Illegal in-place division of unit types.");
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
+ LL_FORCE_INLINE bool operator == (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue == convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
+ LL_FORCE_INLINE bool operator != (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue != convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
+ LL_FORCE_INLINE bool operator < (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue < convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
+ LL_FORCE_INLINE bool operator <= (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue <= convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
+ LL_FORCE_INLINE bool operator > (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue > convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
+ LL_FORCE_INLINE bool operator >= (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue >= convert(other).value();
}
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index dd8660a3c8..fe7482ba29 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -31,6 +31,7 @@
#include <vector>
#include "stdtypes.h"
#include "llpreprocessor.h"
+#include <boost/functional/hash.hpp>
class LLMutex;
@@ -164,6 +165,25 @@ public:
LLAssetID makeAssetID(const LLUUID& session) const;
};
+// Generate a hash of an LLUUID object using the boost hash templates.
+template <>
+struct boost::hash<LLUUID>
+{
+ typedef LLUUID argument_type;
+ typedef std::size_t result_type;
+ result_type operator()(argument_type const& s) const
+ {
+ result_type seed(0);
+
+ for (S32 i = 0; i < UUID_BYTES; ++i)
+ {
+ boost::hash_combine(seed, s.mData[i]);
+ }
+
+ return seed;
+ }
+};
+
#endif
diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp
index 5dff143e5d..6a516f60c0 100644
--- a/indra/llcorehttp/tests/test_refcounted.hpp
+++ b/indra/llcorehttp/tests/test_refcounted.hpp
@@ -30,7 +30,7 @@
#include "test_allocator.h"
-#if 0 // disable all of this because it's hanging win64 builds?
+#if WANT_TESTS_WITH_RACES_THAT_HANG
using namespace LLCoreInt;
namespace tut
@@ -153,5 +153,6 @@ namespace tut
ensure(mMemTotal == (GetMemTotal() - sizeof(RefCounted)));
}
}
-#endif // if 0
+#endif
+
#endif // TEST_LLCOREINT_REF_COUNTED_H_
diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt
index 68dd00d880..f1bc28427d 100644
--- a/indra/llinventory/CMakeLists.txt
+++ b/indra/llinventory/CMakeLists.txt
@@ -23,12 +23,17 @@ set(llinventory_SOURCE_FILES
llfoldertype.cpp
llinventory.cpp
llinventorydefines.cpp
+ llinventorysettings.cpp
llinventorytype.cpp
lllandmark.cpp
llnotecard.cpp
llparcel.cpp
llpermissions.cpp
llsaleinfo.cpp
+ llsettingsbase.cpp
+ llsettingsdaycycle.cpp
+ llsettingssky.cpp
+ llsettingswater.cpp
lltransactionflags.cpp
lluserrelations.cpp
)
@@ -41,7 +46,9 @@ set(llinventory_HEADER_FILES
llfoldertype.h
llinventory.h
llinventorydefines.h
+ llinventorysettings.h
llinventorytype.h
+ llinvtranslationbrdg.h
lllandmark.h
llnotecard.h
llparcel.h
@@ -49,6 +56,10 @@ set(llinventory_HEADER_FILES
llpermissions.h
llpermissionsflags.h
llsaleinfo.h
+ llsettingsbase.h
+ llsettingsdaycycle.h
+ llsettingssky.h
+ llsettingswater.h
lltransactionflags.h
lltransactiontypes.h
lluserrelations.h
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp
index b0daf639fa..7241b3c0c2 100644
--- a/indra/llinventory/llfoldertype.cpp
+++ b/indra/llinventory/llfoldertype.cpp
@@ -100,6 +100,8 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE));
+ addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE));
+
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
};
@@ -147,7 +149,7 @@ bool LLFolderType::lookupIsEnsembleType(EType folder_type)
// static
LLAssetType::EType LLFolderType::folderTypeToAssetType(LLFolderType::EType folder_type)
{
- if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::badLookup())
+ if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::BADLOOKUP)
{
LL_WARNS() << "Converting to unknown asset type " << folder_type << LL_ENDL;
}
diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h
index 515bb05a3f..85b86f9ce5 100644
--- a/indra/llinventory/llfoldertype.h
+++ b/indra/llinventory/llfoldertype.h
@@ -91,6 +91,8 @@ public:
FT_MARKETPLACE_STOCK = 54,
FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only.
+ FT_SETTINGS = 56,
+
FT_COUNT,
FT_NONE = -1
diff --git a/indra/llinventory/llinventorydefines.h b/indra/llinventory/llinventorydefines.h
index 3881fb1fd7..54562673f3 100644
--- a/indra/llinventory/llinventorydefines.h
+++ b/indra/llinventory/llinventorydefines.h
@@ -81,9 +81,10 @@ public:
II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000,
// Whether a returned object is composed of multiple items.
- II_FLAGS_WEARABLES_MASK = 0xff,
- // Wearables use the low order byte of flags to store the
- // LLWearableType::EType enumeration found in newview/llwearable.h
+ II_FLAGS_SUBTYPE_MASK = 0x0000ff,
+ // Some items like Wearables and settings use the low order byte
+ // of flags to store the sub type of the inventory item.
+ // see LLWearableType::EType enumeration found in newview/llwearable.h
II_FLAGS_PERM_OVERWRITE_MASK = (II_FLAGS_OBJECT_SLAM_PERM |
II_FLAGS_OBJECT_SLAM_SALE |
diff --git a/indra/llinventory/llinventorysettings.cpp b/indra/llinventory/llinventorysettings.cpp
new file mode 100644
index 0000000000..fdad50e8d4
--- /dev/null
+++ b/indra/llinventory/llinventorysettings.cpp
@@ -0,0 +1,116 @@
+/**
+* @file llinventorysettings.cpp
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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 "linden_common.h"
+#include "llinventorysettings.h"
+#include "llinventorytype.h"
+#include "llinventorydefines.h"
+#include "lldictionary.h"
+#include "llsingleton.h"
+#include "llinvtranslationbrdg.h"
+
+//=========================================================================
+namespace {
+ LLTranslationBridge::ptr_t sTranslator;
+}
+
+//=========================================================================
+struct SettingsEntry : public LLDictionaryEntry
+{
+ SettingsEntry(const std::string &name,
+ const std::string& default_new_name,
+ LLInventoryType::EIconName iconName) :
+ LLDictionaryEntry(name),
+ mDefaultNewName(default_new_name),
+ mLabel(name),
+ mIconName(iconName)
+ {
+ std::string transdname = sTranslator->getString(mLabel);
+ if (!transdname.empty())
+ {
+ mLabel = transdname;
+ }
+ }
+
+ std::string mLabel;
+ std::string mDefaultNewName; //keep mLabel for backward compatibility
+ LLInventoryType::EIconName mIconName;
+};
+
+class LLSettingsDictionary : public LLSingleton<LLSettingsDictionary>,
+ public LLDictionary<LLSettingsType::type_e, SettingsEntry>
+{
+ LLSINGLETON(LLSettingsDictionary);
+
+ void initSingleton();
+};
+
+LLSettingsDictionary::LLSettingsDictionary()
+{
+}
+
+void LLSettingsDictionary::initSingleton()
+{
+ addEntry(LLSettingsType::ST_SKY, new SettingsEntry("sky", "New Sky", LLInventoryType::ICONNAME_SETTINGS_SKY));
+ addEntry(LLSettingsType::ST_WATER, new SettingsEntry("water", "New Water", LLInventoryType::ICONNAME_SETTINGS_WATER));
+ addEntry(LLSettingsType::ST_DAYCYCLE, new SettingsEntry("day", "New Day", LLInventoryType::ICONNAME_SETTINGS_DAY));
+ addEntry(LLSettingsType::ST_NONE, new SettingsEntry("none", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
+ addEntry(LLSettingsType::ST_INVALID, new SettingsEntry("invalid", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
+}
+
+//=========================================================================
+
+LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
+{
+ return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
+}
+
+LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type)
+{
+ const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
+ if (!entry)
+ return getIconName(ST_INVALID);
+ return entry->mIconName;
+}
+
+std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
+{
+ const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
+ if (!entry)
+ return getDefaultName(ST_INVALID);
+ return entry->mDefaultNewName;
+}
+
+void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
+{
+ sTranslator = trans;
+}
+
+void LLSettingsType::cleanupClass()
+{
+ sTranslator.reset();
+}
diff --git a/indra/llinventory/llinventorysettings.h b/indra/llinventory/llinventorysettings.h
new file mode 100644
index 0000000000..906540689c
--- /dev/null
+++ b/indra/llinventory/llinventorysettings.h
@@ -0,0 +1,56 @@
+/**
+* @file llinventorysettings.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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_INVENTORY_SETTINGS_H
+#define LL_INVENTORY_SETTINGS_H
+
+#include "llinventorytype.h"
+#include "llinvtranslationbrdg.h"
+
+class LLSettingsType
+{
+public:
+ enum type_e
+ {
+ ST_SKY = 0,
+ ST_WATER = 1,
+ ST_DAYCYCLE = 2,
+
+ ST_INVALID = 255,
+ ST_NONE = -1
+ };
+
+ static type_e fromInventoryFlags(U32 flags);
+ static LLInventoryType::EIconName getIconName(type_e type);
+ static std::string getDefaultName(type_e type);
+
+ static void initClass(LLTranslationBridge::ptr_t &trans);
+ static void cleanupClass();
+};
+
+
+#endif
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 7399e1bca4..853ed655f5 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
+ addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS));
}
@@ -145,6 +146,14 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 47 AT_NONE
LLInventoryType::IT_NONE, // 48 AT_NONE
LLInventoryType::IT_MESH, // 49 AT_MESH
+
+ LLInventoryType::IT_NONE, // 50 AT_RESERVED_1
+ LLInventoryType::IT_NONE, // 51 AT_RESERVED_2
+ LLInventoryType::IT_NONE, // 52 AT_RESERVED_3
+ LLInventoryType::IT_NONE, // 53 AT_RESERVED_4
+ LLInventoryType::IT_NONE, // 54 AT_RESERVED_5
+
+ LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS
};
// static
@@ -200,6 +209,12 @@ bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type)
}
}
+// Should show permissions that apply only to objects rezed in world.
+bool LLInventoryType::showInWorldPermissions(LLInventoryType::EType type)
+{
+ return (type != IT_SETTINGS);
+}
+
bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type,
LLAssetType::EType asset_type)
{
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 891ab217fd..72092b1d8b 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -64,7 +64,8 @@ public:
IT_MESH = 22,
IT_WIDGET = 23,
IT_PERSON = 24,
- IT_COUNT = 25,
+ IT_SETTINGS = 25,
+ IT_COUNT = 26,
IT_UNKNOWN = 255,
IT_NONE = -1
@@ -111,6 +112,11 @@ public:
ICONNAME_LINKFOLDER,
ICONNAME_MESH,
+ ICONNAME_SETTINGS,
+ ICONNAME_SETTINGS_SKY,
+ ICONNAME_SETTINGS_WATER,
+ ICONNAME_SETTINGS_DAY,
+
ICONNAME_INVALID,
ICONNAME_UNKNOWN,
ICONNAME_COUNT,
@@ -130,6 +136,8 @@ public:
// true if this type cannot have restricted permissions.
static bool cannotRestrictPermissions(EType type);
+ static bool showInWorldPermissions(EType type);
+
private:
// don't instantiate or derive one of these objects
LLInventoryType( void );
diff --git a/indra/llinventory/llinvtranslationbrdg.h b/indra/llinventory/llinvtranslationbrdg.h
new file mode 100644
index 0000000000..fbd887030a
--- /dev/null
+++ b/indra/llinventory/llinvtranslationbrdg.h
@@ -0,0 +1,41 @@
+/**
+* @file llinvtranslationbrdg.h
+* @brief Translation adapter for inventory.
+*
+* $LicenseInfo:firstyear=2002&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_TRANSLATIONBRDG_H
+#define LL_TRANSLATIONBRDG_H
+
+class LLTranslationBridge
+{
+public:
+ typedef std::shared_ptr<LLTranslationBridge> ptr_t;
+
+ // clang needs this to be happy
+ virtual ~LLTranslationBridge() {}
+
+ virtual std::string getString(const std::string &xml_desc) = 0;
+};
+
+#endif
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 0908613c10..aff7f86fd4 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -231,6 +231,9 @@ void LLParcel::init(const LLUUID &owner_id,
setAllowGroupAVSounds(TRUE);
setAllowAnyAVSounds(TRUE);
setHaveNewParcelLimitData(FALSE);
+
+ setRegionAllowEnvironmentOverride(FALSE);
+ setParcelEnvironmentVersion(-1);
}
void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 135d0ca7b9..2497a069d7 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -34,6 +34,7 @@
#include "llpermissions.h"
#include "lltimer.h"
#include "v3math.h"
+#include "llsettingsdaycycle.h"
// Grid out of which parcels taken is stepped every 4 meters.
const F32 PARCEL_GRID_STEP_METERS = 4.f;
@@ -510,6 +511,10 @@ public:
{ return mRegionDenyAgeUnverifiedOverride; }
BOOL getRegionAllowAccessOverride() const
{ return mRegionAllowAccessoverride; }
+ BOOL getRegionAllowEnvironmentOverride() const
+ { return mRegionAllowEnvironmentOverride; }
+ S32 getParcelEnvironmentVersion() const
+ { return mCurrentEnvironmentVersion; }
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
@@ -580,6 +585,9 @@ public:
void setRegionDenyAnonymousOverride(BOOL override) { mRegionDenyAnonymousOverride = override; }
void setRegionDenyAgeUnverifiedOverride(BOOL override) { mRegionDenyAgeUnverifiedOverride = override; }
void setRegionAllowAccessOverride(BOOL override) { mRegionAllowAccessoverride = override; }
+ void setRegionAllowEnvironmentOverride(BOOL override) { mRegionAllowEnvironmentOverride = override; }
+
+ void setParcelEnvironmentVersion(S32 version) { mCurrentEnvironmentVersion = version; }
// Accessors for parcel sellWithObjects
void setPreviousOwnerID(LLUUID prev_owner) { mPreviousOwnerID = prev_owner; }
@@ -589,8 +597,7 @@ public:
LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; }
BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; }
BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
-
-
+
protected:
LLUUID mID;
LLUUID mOwnerID;
@@ -662,10 +669,13 @@ protected:
BOOL mRegionDenyAnonymousOverride;
BOOL mRegionDenyAgeUnverifiedOverride;
BOOL mRegionAllowAccessoverride;
+ BOOL mRegionAllowEnvironmentOverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
+ S32 mCurrentEnvironmentVersion;
-
+ bool mIsDefaultDayCycle;
+
public:
// HACK, make private
S32 mLocalID;
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
new file mode 100644
index 0000000000..2adbb213e6
--- /dev/null
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -0,0 +1,691 @@
+/**
+* @file llsettingsbase.cpp
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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 "llsettingsbase.h"
+
+#include "llmath.h"
+#include <algorithm>
+
+#include "llsdserialize.h"
+
+//=========================================================================
+namespace
+{
+ const LLSettingsBase::TrackPosition BREAK_POINT = 0.5;
+}
+
+const LLSettingsBase::TrackPosition LLSettingsBase::INVALID_TRACKPOS(-1.0);
+
+//=========================================================================
+std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings)
+{
+ LLSDSerialize::serialize(settings.getSettings(), os, LLSDSerialize::LLSD_NOTATION);
+
+ return os;
+}
+
+//=========================================================================
+const std::string LLSettingsBase::SETTING_ID("id");
+const std::string LLSettingsBase::SETTING_NAME("name");
+const std::string LLSettingsBase::SETTING_HASH("hash");
+const std::string LLSettingsBase::SETTING_TYPE("type");
+const std::string LLSettingsBase::SETTING_ASSETID("asset_id");
+const std::string LLSettingsBase::SETTING_FLAGS("flags");
+
+const U32 LLSettingsBase::FLAG_NOCOPY(0x01 << 0);
+const U32 LLSettingsBase::FLAG_NOMOD(0x01 << 1);
+const U32 LLSettingsBase::FLAG_NOTRANS(0x01 << 2);
+
+//=========================================================================
+LLSettingsBase::LLSettingsBase():
+ mSettings(LLSD::emptyMap()),
+ mDirty(true),
+ mAssetID(),
+ mBlendedFactor(0.0)
+{
+}
+
+LLSettingsBase::LLSettingsBase(const LLSD setting) :
+ mSettings(setting),
+ mDirty(true),
+ mAssetID(),
+ mBlendedFactor(0.0)
+{
+}
+
+//=========================================================================
+void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix)
+{
+ mSettings = interpolateSDMap(mSettings, other.mSettings, mix);
+ setDirtyFlag(true);
+}
+
+LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const
+{
+ LLSD newSettings;
+
+ for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
+ {
+ std::string key_name = (*it).first;
+ LLSD value = (*it).second;
+
+ LLSD::Type setting_type = value.type();
+ switch (setting_type)
+ {
+ case LLSD::TypeMap:
+ newSettings[key_name] = combineSDMaps(value, LLSD());
+ break;
+ case LLSD::TypeArray:
+ newSettings[key_name] = LLSD::emptyArray();
+ for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+ {
+ newSettings[key_name].append(*ita);
+ }
+ break;
+ //case LLSD::TypeInteger:
+ //case LLSD::TypeReal:
+ //case LLSD::TypeBoolean:
+ //case LLSD::TypeString:
+ //case LLSD::TypeUUID:
+ //case LLSD::TypeURI:
+ //case LLSD::TypeDate:
+ //case LLSD::TypeBinary:
+ default:
+ newSettings[key_name] = value;
+ break;
+ }
+ }
+
+ if (!other.isUndefined())
+ {
+ for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
+ {
+ std::string key_name = (*it).first;
+ LLSD value = (*it).second;
+
+ LLSD::Type setting_type = value.type();
+ switch (setting_type)
+ {
+ case LLSD::TypeMap:
+ newSettings[key_name] = combineSDMaps(value, LLSD());
+ break;
+ case LLSD::TypeArray:
+ newSettings[key_name] = LLSD::emptyArray();
+ for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+ {
+ newSettings[key_name].append(*ita);
+ }
+ break;
+ //case LLSD::TypeInteger:
+ //case LLSD::TypeReal:
+ //case LLSD::TypeBoolean:
+ //case LLSD::TypeString:
+ //case LLSD::TypeUUID:
+ //case LLSD::TypeURI:
+ //case LLSD::TypeDate:
+ //case LLSD::TypeBinary:
+ default:
+ newSettings[key_name] = value;
+ break;
+ }
+ }
+ }
+
+ return newSettings;
+}
+
+LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F64 mix) const
+{
+ LLSD newSettings;
+
+ stringset_t skip = getSkipInterpolateKeys();
+ stringset_t slerps = getSlerpKeys();
+
+ for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
+ {
+ std::string key_name = (*it).first;
+ LLSD value = (*it).second;
+
+ if (skip.find(key_name) != skip.end())
+ continue;
+
+ if (!other.has(key_name))
+ { // The other does not contain this setting, keep the original value
+ // TODO: Should I blend this out instead?
+ newSettings[key_name] = value;
+ continue;
+ }
+ LLSD::Type setting_type = value.type();
+ LLSD other_value = other[key_name];
+
+ if (other_value.type() != setting_type)
+ {
+ // The data type mismatched between this and other. Hard switch when we pass the break point
+ // but issue a warning.
+ LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
+ newSettings[key_name] = (mix > BREAK_POINT) ? other_value : value;
+ continue;
+ }
+
+ switch (setting_type)
+ {
+ case LLSD::TypeInteger:
+ // lerp between the two values rounding the result to the nearest integer.
+ newSettings[key_name] = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
+ break;
+ case LLSD::TypeReal:
+ // lerp between the two values.
+ newSettings[key_name] = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
+ break;
+ case LLSD::TypeMap:
+ // deep copy.
+ newSettings[key_name] = interpolateSDMap(value, other_value, mix);
+ break;
+
+ case LLSD::TypeArray:
+ {
+ LLSD newvalue(LLSD::emptyArray());
+
+ if (slerps.find(key_name) != slerps.end())
+ {
+ LLQuaternion a(value);
+ LLQuaternion b(other_value);
+ LLQuaternion q = slerp(mix, a, b);
+ newvalue = q.getValue();
+ }
+ else
+ { // TODO: We could expand this to inspect the type and do a deep lerp based on type.
+ // for now assume a heterogeneous array of reals.
+ size_t len = std::max(value.size(), other_value.size());
+
+ for (size_t i = 0; i < len; ++i)
+ {
+
+ newvalue[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
+ }
+ }
+
+ newSettings[key_name] = newvalue;
+ }
+
+ break;
+
+ case LLSD::TypeUUID:
+ newSettings[key_name] = value.asUUID();
+ break;
+
+// case LLSD::TypeBoolean:
+// case LLSD::TypeString:
+// case LLSD::TypeURI:
+// case LLSD::TypeBinary:
+// case LLSD::TypeDate:
+ default:
+ // atomic or unknown data types. Lerping between them does not make sense so switch at the break.
+ newSettings[key_name] = (mix > BREAK_POINT) ? other_value : value;
+ break;
+ }
+ }
+
+ // Special handling cases
+ // Flags
+ if (settings.has(SETTING_FLAGS))
+ {
+ U32 flags = (U32)settings[SETTING_FLAGS].asInteger();
+ if (other.has(SETTING_FLAGS))
+ flags |= (U32)other[SETTING_FLAGS].asInteger();
+
+ newSettings[SETTING_FLAGS] = LLSD::Integer(flags);
+ }
+
+ // Now add anything that is in other but not in the settings
+ for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
+ {
+ // TODO: Should I blend this in instead?
+ if (skip.find((*it).first) == skip.end())
+ continue;
+
+ if (!settings.has((*it).first))
+ continue;
+
+ newSettings[(*it).first] = (*it).second;
+ }
+
+ return newSettings;
+}
+
+LLSettingsBase::stringset_t LLSettingsBase::getSkipInterpolateKeys() const
+{
+ static stringset_t skipSet;
+
+ if (skipSet.empty())
+ {
+ skipSet.insert(SETTING_FLAGS);
+ skipSet.insert(SETTING_HASH);
+ }
+
+ return skipSet;
+}
+
+LLSD LLSettingsBase::getSettings() const
+{
+ return mSettings;
+}
+
+LLSD LLSettingsBase::cloneSettings() const
+{
+ return combineSDMaps(getSettings(), LLSD());
+}
+
+size_t LLSettingsBase::getHash() const
+{ // get a shallow copy of the LLSD filtering out values to not include in the hash
+ LLSD hash_settings = llsd_shallow(getSettings(),
+ LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true));
+
+ boost::hash<LLSD> hasher;
+ return hasher(hash_settings);
+}
+
+bool LLSettingsBase::validate()
+{
+ validation_list_t validations = getValidationList();
+
+ if (!mSettings.has(SETTING_TYPE))
+ {
+ mSettings[SETTING_TYPE] = getSettingsType();
+ }
+
+ LLSD result = LLSettingsBase::settingValidation(mSettings, validations);
+
+ if (result["errors"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Validation errors: " << result["errors"] << LL_ENDL;
+ }
+ if (result["warnings"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Validation warnings: " << result["warnings"] << LL_ENDL;
+ }
+
+ return result["success"].asBoolean();
+}
+
+LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations)
+{
+ static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 32));
+ static Validator validateId(SETTING_ID, false, LLSD::TypeUUID);
+ static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger);
+ static Validator validateType(SETTING_TYPE, false, LLSD::TypeString);
+ static Validator validateAssetId(SETTING_ASSETID, false, LLSD::TypeUUID);
+ static Validator validateFlags(SETTING_FLAGS, false, LLSD::TypeInteger);
+ stringset_t validated;
+ stringset_t strip;
+ bool isValid(true);
+ LLSD errors(LLSD::emptyArray());
+ LLSD warnings(LLSD::emptyArray());
+
+ // Fields common to all settings.
+ if (!validateName.verify(settings))
+ {
+ errors.append( LLSD::String("Unable to validate 'name'.") );
+ isValid = false;
+ }
+ validated.insert(validateName.getName());
+
+ if (!validateId.verify(settings))
+ {
+ errors.append( LLSD::String("Unable to validate 'id'.") );
+ isValid = false;
+ }
+ validated.insert(validateId.getName());
+
+ if (!validateHash.verify(settings))
+ {
+ errors.append( LLSD::String("Unable to validate 'hash'.") );
+ isValid = false;
+ }
+ validated.insert(validateHash.getName());
+
+ if (!validateAssetId.verify(settings))
+ {
+ errors.append(LLSD::String("Invalid asset Id"));
+ isValid = false;
+ }
+ validated.insert(validateAssetId.getName());
+
+ if (!validateType.verify(settings))
+ {
+ errors.append( LLSD::String("Unable to validate 'type'.") );
+ isValid = false;
+ }
+ validated.insert(validateType.getName());
+
+ if (!validateFlags.verify(settings))
+ {
+ errors.append(LLSD::String("Unable to validate 'flags'."));
+ isValid = false;
+ }
+ validated.insert(validateFlags.getName());
+
+ // Fields for specific settings.
+ for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv)
+ {
+#ifdef VALIDATION_DEBUG
+ LLSD oldvalue;
+ if (settings.has((*itv).getName()))
+ {
+ oldvalue = llsd_clone(mSettings[(*itv).getName()]);
+ }
+#endif
+
+ if (!(*itv).verify(settings))
+ {
+ std::stringstream errtext;
+
+ errtext << "Settings LLSD fails validation and could not be corrected for '" << (*itv).getName() << "'!\n";
+ errors.append( errtext.str() );
+ isValid = false;
+ }
+ validated.insert((*itv).getName());
+
+#ifdef VALIDATION_DEBUG
+ if (!oldvalue.isUndefined())
+ {
+ if (!compare_llsd(settings[(*itv).getName()], oldvalue))
+ {
+ LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << settings[(*itv).getName()] << LL_ENDL;
+ }
+ }
+#endif
+ }
+
+ // strip extra entries
+ for (LLSD::map_const_iterator itm = settings.beginMap(); itm != settings.endMap(); ++itm)
+ {
+ if (validated.find((*itm).first) == validated.end())
+ {
+ std::stringstream warntext;
+
+ warntext << "Stripping setting '" << (*itm).first << "'";
+ warnings.append( warntext.str() );
+ strip.insert((*itm).first);
+ }
+ }
+
+ for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its)
+ {
+ settings.erase(*its);
+ }
+
+ return LLSDMap("success", LLSD::Boolean(isValid))
+ ("errors", errors)
+ ("warnings", warnings);
+}
+
+//=========================================================================
+bool LLSettingsBase::Validator::verify(LLSD &data)
+{
+ if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined()))
+ {
+ if (!mDefault.isUndefined())
+ {
+ data[mName] = mDefault;
+ return true;
+ }
+ if (mRequired)
+ LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "' with no default." << LL_ENDL;
+ return !mRequired;
+ }
+
+ if (data[mName].type() != mType)
+ {
+ LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL;
+ return false;
+ }
+
+ if (!mVerify.empty() && !mVerify(data[mName]))
+ {
+ LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL;
+ return false;
+ }
+
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyColor(LLSD &value)
+{
+ return (value.size() == 3 || value.size() == 4);
+}
+
+bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length)
+{
+ return (value.size() == length);
+}
+
+bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
+{
+ if (value.size() != length)
+ return false;
+
+ LLSD newvector;
+
+ switch (length)
+ {
+ case 2:
+ {
+ LLVector2 vect(value);
+
+ if (is_approx_equal(vect.normalize(), 1.0f))
+ return true;
+ newvector = vect.getValue();
+ break;
+ }
+ case 3:
+ {
+ LLVector3 vect(value);
+
+ if (is_approx_equal(vect.normalize(), 1.0f))
+ return true;
+ newvector = vect.getValue();
+ break;
+ }
+ case 4:
+ {
+ LLVector4 vect(value);
+
+ if (is_approx_equal(vect.normalize(), 1.0f))
+ return true;
+ newvector = vect.getValue();
+ break;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals)
+{
+ for (S32 index = 0; index < value.size(); ++index)
+ {
+ if (minvals[index].asString() != "*")
+ {
+ if (minvals[index].asReal() > value[index].asReal())
+ {
+ value[index] = minvals[index].asReal();
+ }
+ }
+ if (maxvals[index].asString() != "*")
+ {
+ if (maxvals[index].asReal() < value[index].asReal())
+ {
+ value[index] = maxvals[index].asReal();
+ }
+ }
+ }
+
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value)
+{
+ return (value.size() == 4);
+}
+
+bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
+{
+ if (value.size() != 4)
+ return false;
+
+ LLQuaternion quat(value);
+
+ if (is_approx_equal(quat.normalize(), 1.0f))
+ return true;
+
+ LLSD newquat = quat.getValue();
+ for (S32 index = 0; index < 4; ++index)
+ {
+ value[index] = newquat[index];
+ }
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
+{
+ F64 real = value.asReal();
+
+ F64 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal());
+
+ if (is_approx_equal(clampedval, real))
+ return true;
+
+ value = LLSD::Real(clampedval);
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
+{
+ S32 ival = value.asInteger();
+
+ S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger());
+
+ if (clampedval == ival)
+ return true;
+
+ value = LLSD::Integer(clampedval);
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length)
+{
+ std::string sval = value.asString();
+
+ if (!sval.empty())
+ {
+ sval = sval.substr(0, length);
+ value = LLSD::String(sval);
+ }
+ return true;
+}
+
+//=========================================================================
+void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
+{
+ setBlendFactor(blendf);
+}
+
+F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_in)
+{
+ LLSettingsBase::TrackPosition blendf = blendf_in;
+ if (blendf >= 1.0)
+ {
+ triggerComplete();
+ return 1.0;
+ }
+ blendf = llclamp(blendf, 0.0f, 1.0f);
+
+ if (mTarget)
+ {
+ mTarget->replaceSettings(mInitial->getSettings());
+ if (!mFinal || (mInitial == mFinal) || (blendf == 0.0))
+ { // this is a trivial blend. Results will be identical to the initial.
+ return blendf;
+ }
+ mTarget->blend(mFinal, blendf);
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "No target for settings blender." << LL_ENDL;
+ }
+
+ return blendf;
+}
+
+void LLSettingsBlender::triggerComplete()
+{
+ if (mTarget)
+ mTarget->replaceSettings(mFinal->getSettings());
+ LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon
+ mOnFinished(shared_from_this());
+}
+
+//-------------------------------------------------------------------------
+const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(0.001);
+
+LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const
+{
+ return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen);
+}
+
+void LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
+{
+ mTimeSpent += timedelta;
+ mTimeDeltaPassed += timedelta;
+
+ if (mTimeSpent > mBlendSpan)
+ {
+ mIgnoreTimeDelta = false;
+ triggerComplete();
+ return;
+ }
+
+ if ((mTimeDeltaPassed < mTimeDeltaThreshold) && (!mIgnoreTimeDelta))
+ {
+ return;
+ }
+
+ LLSettingsBase::BlendFactor blendf = calculateBlend(mTimeSpent, mBlendSpan);
+ mTimeDeltaPassed = LLSettingsBase::Seconds(0.0);
+
+ if (fabs(mLastBlendF - blendf) < mBlendFMinDelta)
+ {
+ return;
+ }
+
+ mLastBlendF = blendf;
+
+ update(blendf);
+}
diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h
new file mode 100644
index 0000000000..aea1bc3fde
--- /dev/null
+++ b/indra/llinventory/llsettingsbase.h
@@ -0,0 +1,507 @@
+/**
+* @file llsettingsbase.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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_BASE_H
+#define LL_SETTINGS_BASE_H
+
+#include <string>
+#include <map>
+#include <vector>
+#include <boost/signals2.hpp>
+
+#include "llsd.h"
+#include "llsdutil.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "llquaternion.h"
+#include "v4color.h"
+#include "v3color.h"
+#include "llunits.h"
+
+#include "llinventorysettings.h"
+
+#define PTR_NAMESPACE std
+#define SETTINGS_OVERRIDE override
+
+class LLSettingsBase :
+ public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBase>,
+ private boost::noncopyable
+{
+ friend class LLEnvironment;
+ friend class LLSettingsDay;
+
+ friend std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings);
+
+protected:
+ LOG_CLASS(LLSettingsBase);
+public:
+ typedef F64Seconds Seconds;
+ typedef F64 BlendFactor;
+ typedef F32 TrackPosition; // 32-bit as these are stored in LLSD as such
+ static const TrackPosition INVALID_TRACKPOS;
+
+ static const std::string SETTING_ID;
+ static const std::string SETTING_NAME;
+ static const std::string SETTING_HASH;
+ static const std::string SETTING_TYPE;
+ static const std::string SETTING_ASSETID;
+ static const std::string SETTING_FLAGS;
+
+ static const U32 FLAG_NOCOPY;
+ static const U32 FLAG_NOMOD;
+ static const U32 FLAG_NOTRANS;
+
+ typedef std::map<std::string, S32> parammapping_t;
+
+ typedef PTR_NAMESPACE::shared_ptr<LLSettingsBase> ptr_t;
+
+ virtual ~LLSettingsBase() { };
+
+ //---------------------------------------------------------------------
+ virtual std::string getSettingsType() const = 0;
+
+ virtual LLSettingsType::type_e getSettingsTypeValue() const = 0;
+
+ //---------------------------------------------------------------------
+ // Settings status
+ inline bool hasSetting(const std::string &param) const { return mSettings.has(param); }
+ inline bool isDirty() const { return mDirty; }
+ inline bool isVeryDirty() const { return mReplaced; }
+ inline void setDirtyFlag(bool dirty) { mDirty = dirty; clearAssetId(); }
+
+ size_t getHash() const; // Hash will not include Name, ID or a previously stored Hash
+
+ inline LLUUID getId() const
+ {
+ return getValue(SETTING_ID).asUUID();
+ }
+
+ inline std::string getName() const
+ {
+ return getValue(SETTING_NAME).asString();
+ }
+
+ inline void setName(std::string val)
+ {
+ setValue(SETTING_NAME, val);
+ }
+
+ inline LLUUID getAssetId() const
+ {
+ if (mSettings.has(SETTING_ASSETID))
+ return mSettings[SETTING_ASSETID].asUUID();
+ return LLUUID();
+ }
+
+ inline U32 getFlags() const
+ {
+ if (mSettings.has(SETTING_FLAGS))
+ return static_cast<U32>(mSettings[SETTING_FLAGS].asInteger());
+ return 0;
+ }
+
+ inline void setFlags(U32 value)
+ {
+ setLLSD(SETTING_FLAGS, LLSD::Integer(value));
+ }
+
+ inline bool getFlag(U32 flag) const
+ {
+ if (mSettings.has(SETTING_FLAGS))
+ return ((U32)mSettings[SETTING_FLAGS].asInteger() & flag) == flag;
+ return false;
+ }
+
+ inline void setFlag(U32 flag)
+ {
+ U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
+
+ flags |= flag;
+
+ if (flags)
+ mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
+ else
+ mSettings.erase(SETTING_FLAGS);
+ }
+
+ inline void clearFlag(U32 flag)
+ {
+ U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
+
+ flags &= ~flag;
+
+ if (flags)
+ mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
+ else
+ mSettings.erase(SETTING_FLAGS);
+ }
+
+ virtual void replaceSettings(LLSD settings)
+ {
+ mBlendedFactor = 0.0;
+ setDirtyFlag(true);
+ mReplaced = true;
+ mSettings = settings;
+ }
+
+ virtual LLSD getSettings() const;
+
+ //---------------------------------------------------------------------
+ //
+ inline void setLLSD(const std::string &name, const LLSD &value)
+ {
+ mSettings[name] = value;
+ mDirty = true;
+ if (name != SETTING_ASSETID)
+ clearAssetId();
+ }
+
+ inline void setValue(const std::string &name, const LLSD &value)
+ {
+ setLLSD(name, value);
+ }
+
+ inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const
+ {
+ if (!mSettings.has(name))
+ return deflt;
+ return mSettings[name];
+ }
+
+ inline void setValue(const std::string &name, F32 v)
+ {
+ setLLSD(name, LLSD::Real(v));
+ }
+
+ inline void setValue(const std::string &name, const LLVector2 &value)
+ {
+ setValue(name, value.getValue());
+ }
+
+ inline void setValue(const std::string &name, const LLVector3 &value)
+ {
+ setValue(name, value.getValue());
+ }
+
+ inline void setValue(const std::string &name, const LLVector4 &value)
+ {
+ setValue(name, value.getValue());
+ }
+
+ inline void setValue(const std::string &name, const LLQuaternion &value)
+ {
+ setValue(name, value.getValue());
+ }
+
+ inline void setValue(const std::string &name, const LLColor3 &value)
+ {
+ setValue(name, value.getValue());
+ }
+
+ inline void setValue(const std::string &name, const LLColor4 &value)
+ {
+ setValue(name, value.getValue());
+ }
+
+ inline BlendFactor getBlendFactor() const
+ {
+ return mBlendedFactor;
+ }
+
+ // Note this method is marked const but may modify the settings object.
+ // (note the internal const cast). This is so that it may be called without
+ // special consideration from getters.
+ inline void update() const
+ {
+ if ((!mDirty) && (!mReplaced))
+ return;
+ (const_cast<LLSettingsBase *>(this))->updateSettings();
+ }
+
+ virtual void blend(const ptr_t &end, BlendFactor blendf) = 0;
+
+ virtual bool validate();
+
+ virtual ptr_t buildDerivedClone() const = 0;
+
+ class Validator
+ {
+ public:
+ typedef boost::function<bool(LLSD &)> verify_pr;
+
+ Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) :
+ mName(name),
+ mRequired(required),
+ mType(type),
+ mVerify(verify),
+ mDefault(defval)
+ { }
+
+ std::string getName() const { return mName; }
+ bool isRequired() const { return mRequired; }
+ LLSD::Type getType() const { return mType; }
+
+ bool verify(LLSD &data);
+
+ // Some basic verifications
+ static bool verifyColor(LLSD &value);
+ static bool verifyVector(LLSD &value, S32 length);
+ static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals);
+ static bool verifyVectorNormalized(LLSD &value, S32 length);
+ static bool verifyQuaternion(LLSD &value);
+ static bool verifyQuaternionNormal(LLSD &value);
+ static bool verifyFloatRange(LLSD &value, LLSD range);
+ static bool verifyIntegerRange(LLSD &value, LLSD range);
+ static bool verifyStringLength(LLSD &value, S32 length);
+
+ private:
+ std::string mName;
+ bool mRequired;
+ LLSD::Type mType;
+ verify_pr mVerify;
+ LLSD mDefault;
+ };
+ typedef std::vector<Validator> validation_list_t;
+
+ static LLSD settingValidation(LLSD &settings, validation_list_t &validations);
+
+ inline void setAssetId(LLUUID value)
+ { // note that this skips setLLSD
+ mSettings[SETTING_ASSETID] = value;
+ }
+
+ inline void clearAssetId()
+ {
+ if (mSettings.has(SETTING_ASSETID))
+ mSettings.erase(SETTING_ASSETID);
+ }
+
+protected:
+
+ LLSettingsBase();
+ LLSettingsBase(const LLSD setting);
+
+ static LLSD settingValidation(LLSD settings);
+
+ typedef std::set<std::string> stringset_t;
+
+ // combining settings objects. Customize for specific setting types
+ virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix);
+ LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, BlendFactor mix) const;
+
+ /// when lerping between settings, some may require special handling.
+ /// Get a list of these key to be skipped by the default settings lerp.
+ /// (handling should be performed in the override of lerpSettings.
+ virtual stringset_t getSkipInterpolateKeys() const;
+
+ // A list of settings that represent quaternions and should be slerped
+ // rather than lerped.
+ virtual stringset_t getSlerpKeys() const { return stringset_t(); }
+
+ // Calculate any custom settings that may need to be cached.
+ virtual void updateSettings() { mDirty = false; mReplaced = false; };
+
+ virtual validation_list_t getValidationList() const = 0;
+
+ // Apply any settings that need special handling.
+ virtual void applySpecial(void *) { };
+
+ virtual parammapping_t getParameterMap() const { return parammapping_t(); }
+
+ LLSD mSettings;
+ bool mIsValid;
+ LLAssetID mAssetID;
+
+ LLSD cloneSettings() const;
+
+ inline void setBlendFactor(BlendFactor blendfactor)
+ {
+ mBlendedFactor = blendfactor;
+ }
+
+private:
+ bool mDirty;
+ bool mReplaced; // super dirty!
+
+ LLSD combineSDMaps(const LLSD &first, const LLSD &other) const;
+
+ BlendFactor mBlendedFactor;
+};
+
+
+class LLSettingsBlender : public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBlender>
+{
+ LOG_CLASS(LLSettingsBlender);
+public:
+ typedef PTR_NAMESPACE::shared_ptr<LLSettingsBlender> ptr_t;
+ typedef boost::signals2::signal<void(const ptr_t )> finish_signal_t;
+ typedef boost::signals2::connection connection_t;
+
+ LLSettingsBlender(const LLSettingsBase::ptr_t &target,
+ const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting) :
+ mOnFinished(),
+ mTarget(target),
+ mInitial(initsetting),
+ mFinal(endsetting)
+ {
+ if (mInitial && mTarget)
+ mTarget->replaceSettings(mInitial->getSettings());
+
+ if (!mFinal)
+ mFinal = mInitial;
+ }
+
+ virtual ~LLSettingsBlender() {}
+
+ virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition&)
+ {
+ // note: the 'span' reset parameter is unused by the base class.
+ if (!mInitial)
+ LL_WARNS("BLENDER") << "Reseting blender with empty initial setting. Expect badness in the future." << LL_ENDL;
+
+ mInitial = initsetting;
+ mFinal = endsetting;
+
+ if (!mFinal)
+ mFinal = mInitial;
+
+ if (mTarget)
+ mTarget->replaceSettings(mInitial->getSettings());
+ }
+
+ LLSettingsBase::ptr_t getTarget() const
+ {
+ return mTarget;
+ }
+
+ LLSettingsBase::ptr_t getInitial() const
+ {
+ return mInitial;
+ }
+
+ LLSettingsBase::ptr_t getFinal() const
+ {
+ return mFinal;
+ }
+
+ connection_t setOnFinished(const finish_signal_t::slot_type &onfinished)
+ {
+ return mOnFinished.connect(onfinished);
+ }
+
+ virtual void update(const LLSettingsBase::BlendFactor& blendf);
+ virtual void applyTimeDelta(const LLSettingsBase::Seconds& delta)
+ {
+ llassert(false);
+ // your derived class needs to implement an override of this func
+ }
+
+ virtual F64 setBlendFactor(const LLSettingsBase::BlendFactor& position);
+
+ virtual void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position) { /*NoOp*/ }
+
+protected:
+ void triggerComplete();
+
+ finish_signal_t mOnFinished;
+
+ LLSettingsBase::ptr_t mTarget;
+ LLSettingsBase::ptr_t mInitial;
+ LLSettingsBase::ptr_t mFinal;
+};
+
+class LLSettingsBlenderTimeDelta : public LLSettingsBlender
+{
+ LOG_CLASS(LLSettingsBlenderTimeDelta);
+public:
+ static const LLSettingsBase::BlendFactor MIN_BLEND_DELTA;
+
+ LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target,
+ const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::Seconds& blend_span) :
+ LLSettingsBlender(target, initsetting, endsetting),
+ mBlendSpan(blend_span),
+ mLastUpdate(0.0f),
+ mTimeSpent(0.0f),
+ mTimeDeltaThreshold(0.0f),
+ mTimeDeltaPassed(0.0f),
+ mIgnoreTimeDelta(false),
+ mBlendFMinDelta(MIN_BLEND_DELTA),
+ mLastBlendF(-1.0f)
+ {
+ mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
+ mLastUpdate = mTimeStart;
+ }
+
+ virtual ~LLSettingsBlenderTimeDelta()
+ {
+ }
+
+ virtual void reset(LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition& blend_span) SETTINGS_OVERRIDE
+ {
+ LLSettingsBlender::reset(initsetting, endsetting, blend_span);
+
+ mBlendSpan = blend_span;
+ mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
+ mLastUpdate = mTimeStart;
+ mTimeSpent = LLSettingsBase::Seconds(0.0f);
+ mTimeDeltaPassed = LLSettingsBase::Seconds(0.0f);
+ mLastBlendF = LLSettingsBase::BlendFactor(-1.0f);
+ }
+
+ virtual void applyTimeDelta(const LLSettingsBase::Seconds& timedelta) SETTINGS_OVERRIDE;
+
+ inline void setTimeDeltaThreshold(const LLSettingsBase::Seconds time)
+ {
+ mTimeDeltaThreshold = time;
+ mTimeDeltaPassed = time + LLSettingsBase::Seconds(1.0); // take the next update call.
+ }
+
+ inline LLSettingsBase::Seconds getTimeDeltaThreshold() const
+ {
+ return mTimeDeltaThreshold;
+ }
+
+ inline void setIgnoreTimeDeltaThreshold(bool val) { mIgnoreTimeDelta = val; }
+ inline bool getIgnoreTimeDeltaThreshold() const { return mIgnoreTimeDelta; }
+
+protected:
+ LLSettingsBase::BlendFactor calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const;
+
+ LLSettingsBase::TrackPosition mBlendSpan;
+ LLSettingsBase::Seconds mLastUpdate;
+ LLSettingsBase::Seconds mTimeSpent;
+ LLSettingsBase::Seconds mTimeStart;
+ LLSettingsBase::Seconds mTimeDeltaThreshold;
+ LLSettingsBase::Seconds mTimeDeltaPassed;
+ bool mIgnoreTimeDelta;
+ LLSettingsBase::BlendFactor mBlendFMinDelta;
+ LLSettingsBase::BlendFactor mLastBlendF;
+};
+
+
+#endif
diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp
new file mode 100644
index 0000000000..c911ef23c0
--- /dev/null
+++ b/indra/llinventory/llsettingsdaycycle.cpp
@@ -0,0 +1,895 @@
+/**
+* @file llsettingsdaycycle.cpp
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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 "llsettingsdaycycle.h"
+#include "llerror.h"
+#include <algorithm>
+#include <boost/make_shared.hpp>
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "v3colorutil.h"
+
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+
+#include "llframetimer.h"
+
+//=========================================================================
+namespace
+{
+ LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
+ LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
+
+ template<typename T>
+ inline T get_wrapping_distance(T begin, T end)
+ {
+ if (begin < end)
+ {
+ return end - begin;
+ }
+ else if (begin > end)
+ {
+ return T(1.0) - (begin - end);
+ }
+
+ return 0;
+ }
+
+ 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;
+ }
+
+
+}
+
+//=========================================================================
+const std::string LLSettingsDay::SETTING_KEYID("key_id");
+const std::string LLSettingsDay::SETTING_KEYNAME("key_name");
+const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe");
+const std::string LLSettingsDay::SETTING_KEYHASH("key_hash");
+const std::string LLSettingsDay::SETTING_TRACKS("tracks");
+const std::string LLSettingsDay::SETTING_FRAMES("frames");
+
+const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYLENGTH(120); // 2 mins
+const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYLENGTH(14400); // 4 hours
+const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days
+
+const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYOFFSET(0);
+const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYOFFSET(57600); // +16 hours == -8 hours (SLT time offset)
+const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYOFFSET(86400); // 24 hours
+
+const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0
+const S32 LLSettingsDay::TRACK_GROUND_LEVEL(1);
+const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water
+const S32 LLSettingsDay::FRAME_MAX(56);
+
+const F32 LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR(0.02501f);
+
+const LLUUID LLSettingsDay::DEFAULT_ASSET_ID("94d296c2-6e05-963c-6b62-671199121dbb");
+
+// Minimum value to prevent multislider in edit floaters from eating up frames that 'encroach' on one another's space
+static const F32 DEFAULT_MULTISLIDER_INCREMENT(0.005f);
+//=========================================================================
+LLSettingsDay::LLSettingsDay(const LLSD &data) :
+ LLSettingsBase(data),
+ mInitialized(false)
+{
+ mDayTracks.resize(TRACK_MAX);
+}
+
+LLSettingsDay::LLSettingsDay() :
+ LLSettingsBase(),
+ mInitialized(false)
+{
+ mDayTracks.resize(TRACK_MAX);
+}
+
+//=========================================================================
+LLSD LLSettingsDay::getSettings() const
+{
+ LLSD settings(LLSD::emptyMap());
+
+ if (mSettings.has(SETTING_NAME))
+ settings[SETTING_NAME] = mSettings[SETTING_NAME];
+
+ if (mSettings.has(SETTING_ID))
+ settings[SETTING_ID] = mSettings[SETTING_ID];
+
+ if (mSettings.has(SETTING_ASSETID))
+ settings[SETTING_ASSETID] = mSettings[SETTING_ASSETID];
+
+ settings[SETTING_TYPE] = getSettingsType();
+
+ std::map<std::string, LLSettingsBase::ptr_t> in_use;
+
+ LLSD tracks(LLSD::emptyArray());
+
+ for (CycleList_t::const_iterator itTrack = mDayTracks.begin(); itTrack != mDayTracks.end(); ++itTrack)
+ {
+ LLSD trackout(LLSD::emptyArray());
+
+ for (CycleTrack_t::const_iterator itFrame = (*itTrack).begin(); itFrame != (*itTrack).end(); ++itFrame)
+ {
+ F32 frame = (*itFrame).first;
+ LLSettingsBase::ptr_t data = (*itFrame).second;
+ size_t datahash = data->getHash();
+
+ std::stringstream keyname;
+ keyname << datahash;
+
+ trackout.append(LLSD(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(frame))(SETTING_KEYNAME, keyname.str())));
+ in_use[keyname.str()] = data;
+ }
+ tracks.append(trackout);
+ }
+ settings[SETTING_TRACKS] = tracks;
+
+ LLSD frames(LLSD::emptyMap());
+ for (std::map<std::string, LLSettingsBase::ptr_t>::iterator itFrame = in_use.begin(); itFrame != in_use.end(); ++itFrame)
+ {
+ LLSD framesettings = llsd_clone((*itFrame).second->getSettings(),
+ LLSDMap("*", true)(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false));
+
+ frames[(*itFrame).first] = framesettings;
+ }
+ settings[SETTING_FRAMES] = frames;
+
+ return settings;
+}
+
+bool LLSettingsDay::initialize(bool validate_frames)
+{
+ LLSD tracks = mSettings[SETTING_TRACKS];
+ LLSD frames = mSettings[SETTING_FRAMES];
+
+ // save for later...
+ LLUUID assetid;
+ if (mSettings.has(SETTING_ASSETID))
+ {
+ assetid = mSettings[SETTING_ASSETID].asUUID();
+ LL_WARNS("LAPRAS") << "initializing daycycle with asset id " << assetid << LL_ENDL;
+ }
+
+ std::map<std::string, LLSettingsBase::ptr_t> used;
+
+ for (LLSD::map_const_iterator itFrame = frames.beginMap(); itFrame != frames.endMap(); ++itFrame)
+ {
+ std::string name = (*itFrame).first;
+ LLSD data = (*itFrame).second;
+ LLSettingsBase::ptr_t keyframe;
+
+ if (data[SETTING_TYPE].asString() == "sky")
+ {
+ keyframe = buildSky(data);
+ }
+ else if (data[SETTING_TYPE].asString() == "water")
+ {
+ keyframe = buildWater(data);
+ }
+ else
+ {
+ LL_WARNS("DAYCYCLE") << "Unknown child setting type '" << data[SETTING_TYPE].asString() << "' named '" << name << "'" << LL_ENDL;
+ }
+ if (!keyframe)
+ {
+ LL_WARNS("DAYCYCLE") << "Invalid frame data" << LL_ENDL;
+ continue;
+ }
+
+ used[name] = keyframe;
+ }
+
+ bool haswater(false);
+ bool hassky(false);
+
+ for (S32 i = 0; (i < tracks.size()) && (i < TRACK_MAX); ++i)
+ {
+ mDayTracks[i].clear();
+ LLSD curtrack = tracks[i];
+ for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it)
+ {
+ LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition((*it)[SETTING_KEYKFRAME].asReal());
+ keyframe = llclamp(keyframe, 0.0f, 1.0f);
+ LLSettingsBase::ptr_t setting;
+
+
+ if ((*it).has(SETTING_KEYNAME))
+ {
+ std::string key_name = (*it)[SETTING_KEYNAME];
+ if (i == TRACK_WATER)
+ {
+ setting = used[key_name];
+ if (setting && setting->getSettingsType() != "water")
+ {
+ LL_WARNS("DAYCYCLE") << "Water track referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
+ setting.reset();
+ }
+ }
+ else
+ {
+ setting = used[key_name];
+ if (setting && setting->getSettingsType() != "sky")
+ {
+ LL_WARNS("DAYCYCLE") << "Sky track #" << i << " referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
+ setting.reset();
+ }
+ }
+ }
+
+ if (setting)
+ {
+ if (i == TRACK_WATER)
+ haswater |= true;
+ else
+ hassky |= true;
+
+ if (validate_frames && mDayTracks[i].size() > 0)
+ {
+ // check if we hit close to anything in the list
+ LLSettingsDay::CycleTrack_t::value_type frame = getSettingsNearKeyframe(keyframe, i, DEFAULT_FRAME_SLOP_FACTOR);
+ if (frame.second)
+ {
+ // figure out direction of search
+ LLSettingsBase::TrackPosition found = frame.first;
+ LLSettingsBase::TrackPosition new_frame = keyframe;
+ F32 total_frame_shift = 0;
+ // We consider frame DEFAULT_FRAME_SLOP_FACTOR away as still encroaching, so add minimum increment
+ F32 move_factor = DEFAULT_FRAME_SLOP_FACTOR + DEFAULT_MULTISLIDER_INCREMENT;
+ bool move_forward = true;
+ if ((new_frame < found && (found - new_frame) <= DEFAULT_FRAME_SLOP_FACTOR)
+ || (new_frame > found && (new_frame - found) > DEFAULT_FRAME_SLOP_FACTOR))
+ {
+ move_forward = false;
+ }
+
+ if (move_forward)
+ {
+ CycleTrack_t::iterator iter = mDayTracks[i].find(found);
+ new_frame = found; // for total_frame_shift
+ while (total_frame_shift < 1)
+ {
+ // calculate shifted position from previous found point
+ total_frame_shift += move_factor + (found >= new_frame ? found : found + 1) - new_frame;
+ new_frame = found + move_factor;
+ if (new_frame > 1) new_frame--;
+
+ // we know that current point is too close, go for next one
+ iter++;
+ if (iter == mDayTracks[i].end())
+ {
+ iter = mDayTracks[i].begin();
+ }
+
+ if (((iter->first >= (new_frame - DEFAULT_MULTISLIDER_INCREMENT)) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= iter->first))
+ || ((iter->first < new_frame) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= (iter->first + 1))))
+ {
+ // we are encroaching at new point as well
+ found = iter->first;
+ }
+ else // (new_frame + DEFAULT_FRAME_SLOP_FACTOR < iter->first)
+ {
+ //we found clear spot
+ break;
+ }
+ }
+ }
+ else
+ {
+ CycleTrack_t::reverse_iterator iter = mDayTracks[i].rbegin();
+ while (iter->first != found)
+ {
+ iter++;
+ }
+ new_frame = found; // for total_frame_shift
+ while (total_frame_shift < 1)
+ {
+ // calculate shifted position from current found point
+ total_frame_shift += move_factor + new_frame - (found <= new_frame ? found : found - 1);
+ new_frame = found - move_factor;
+ if (new_frame < 0) new_frame++;
+
+ // we know that current point is too close, go for next one
+ iter++;
+ if (iter == mDayTracks[i].rend())
+ {
+ iter = mDayTracks[i].rbegin();
+ }
+
+ if ((iter->first <= (new_frame + DEFAULT_MULTISLIDER_INCREMENT) && (new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= iter->first)
+ || ((iter->first > new_frame) && ((new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= (iter->first - 1))))
+ {
+ // we are encroaching at new point as well
+ found = iter->first;
+ }
+ else // (new_frame - DEFAULT_FRAME_SLOP_FACTOR > iter->first)
+ {
+ //we found clear spot
+ break;
+ }
+ }
+
+
+ }
+
+ if (total_frame_shift >= 1)
+ {
+ LL_WARNS() << "Could not fix frame position, adding as is to position: " << keyframe << LL_ENDL;
+ }
+ else
+ {
+ // Mark as new position
+ keyframe = new_frame;
+ }
+ }
+ }
+ mDayTracks[i][keyframe] = setting;
+ }
+ }
+ }
+
+ if (!haswater || !hassky)
+ {
+ LL_WARNS("DAYCYCLE") << "Must have at least one water and one sky frame!" << LL_ENDL;
+ return false;
+ }
+ // these are no longer needed and just take up space now.
+ mSettings.erase(SETTING_TRACKS);
+ mSettings.erase(SETTING_FRAMES);
+
+ if (!assetid.isNull())
+ {
+ mSettings[SETTING_ASSETID] = assetid;
+ }
+
+ mInitialized = true;
+ return true;
+}
+
+
+//=========================================================================
+LLSD LLSettingsDay::defaults()
+{
+ static LLSD dfltsetting;
+
+ if (dfltsetting.size() == 0)
+ {
+ dfltsetting[SETTING_NAME] = "_default_";
+ dfltsetting[SETTING_TYPE] = "daycycle";
+
+ LLSD frames(LLSD::emptyMap());
+ LLSD waterTrack;
+ LLSD skyTrack;
+
+
+ const U32 FRAME_COUNT = 8;
+ const F32 FRAME_STEP = 1.0f / F32(FRAME_COUNT);
+ F32 time = 0.0f;
+ for (U32 i = 0; i < FRAME_COUNT; i++)
+ {
+ std::string name("_default_");
+ name += ('a' + i);
+
+ std::string water_frame_name("water:");
+ std::string sky_frame_name("sky:");
+
+ water_frame_name += name;
+ sky_frame_name += name;
+
+ waterTrack[SETTING_KEYKFRAME] = time;
+ waterTrack[SETTING_KEYNAME] = water_frame_name;
+
+ skyTrack[SETTING_KEYKFRAME] = time;
+ skyTrack[SETTING_KEYNAME] = sky_frame_name;
+
+ frames[water_frame_name] = LLSettingsWater::defaults(time);
+ frames[sky_frame_name] = LLSettingsSky::defaults(time);
+
+ time += FRAME_STEP;
+ }
+
+ LLSD tracks;
+ tracks.append(LLSDArray(waterTrack));
+ tracks.append(LLSDArray(skyTrack));
+
+ dfltsetting[SETTING_TRACKS] = tracks;
+ dfltsetting[SETTING_FRAMES] = frames;
+ }
+
+ return dfltsetting;
+}
+
+void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 mix)
+{
+ LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL;
+}
+
+namespace
+{
+ bool validateDayCycleTrack(LLSD &value)
+ {
+ // Trim extra tracks.
+ while (value.size() > LLSettingsDay::TRACK_MAX)
+ {
+ value.erase(value.size() - 1);
+ }
+
+ S32 framecount(0);
+
+ for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track)
+ {
+ S32 index = 0;
+ while (index < (*track).size())
+ {
+ LLSD& elem = (*track)[index];
+
+ ++framecount;
+ if (index >= LLSettingsDay::FRAME_MAX)
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME))
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal())
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ if (!elem.has(LLSettingsDay::SETTING_KEYNAME) &&
+ !elem.has(LLSettingsDay::SETTING_KEYID))
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ LLSettingsBase::TrackPosition frame = elem[LLSettingsDay::SETTING_KEYKFRAME].asReal();
+ if ((frame < 0.0) || (frame > 1.0))
+ {
+ frame = llclamp(frame, 0.0f, 1.0f);
+ elem[LLSettingsDay::SETTING_KEYKFRAME] = frame;
+ }
+ ++index;
+ }
+
+ }
+
+ int waterTracks = value[0].size();
+ int skyTracks = framecount - waterTracks;
+
+ if (waterTracks < 1)
+ {
+ LL_WARNS("SETTINGS") << "Missing water track" << LL_ENDL;
+ return false;
+ }
+
+ if (skyTracks < 1)
+ {
+ LL_WARNS("SETTINGS") << "Missing sky tracks" << LL_ENDL;
+ return false;
+ }
+ return true;
+ }
+
+ bool validateDayCycleFrames(LLSD &value)
+ {
+ bool hasSky(false);
+ bool hasWater(false);
+
+ for (LLSD::map_iterator itf = value.beginMap(); itf != value.endMap(); ++itf)
+ {
+ LLSD frame = (*itf).second;
+
+ std::string ftype = frame[LLSettingsBase::SETTING_TYPE];
+ if (ftype == "sky")
+ {
+ LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList();
+ LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky);
+
+ if (res_sky["success"].asInteger() == 0)
+ {
+ LL_WARNS("SETTINGS") << "Sky setting named '" << (*itf).first << "' validation failed!: " << res_sky << LL_ENDL;
+ LL_WARNS("SETTINGS") << "Sky: " << frame << LL_ENDL;
+ continue;
+ }
+ hasSky |= true;
+ }
+ else if (ftype == "water")
+ {
+ LLSettingsWater::validation_list_t valid_h2o = LLSettingsWater::validationList();
+ LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o);
+ if (res_h2o["success"].asInteger() == 0)
+ {
+ LL_WARNS("SETTINGS") << "Water setting named '" << (*itf).first << "' validation failed!: " << res_h2o << LL_ENDL;
+ LL_WARNS("SETTINGS") << "Water: " << frame << LL_ENDL;
+ continue;
+ }
+ hasWater |= true;
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "Unknown settings block of type '" << ftype << "' named '" << (*itf).first << "'" << LL_ENDL;
+ return false;
+ }
+ }
+
+ if (!hasSky)
+ {
+ LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL;
+ return false;
+ }
+
+ if (!hasWater)
+ {
+ LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL;
+ return false;
+ }
+
+ return true;
+ }
+}
+
+LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const
+{
+ return LLSettingsDay::validationList();
+}
+
+LLSettingsDay::validation_list_t LLSettingsDay::validationList()
+{
+ static validation_list_t validation;
+
+ if (validation.empty())
+ {
+ validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray,
+ &validateDayCycleTrack));
+ validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap,
+ &validateDayCycleFrames));
+ }
+
+ return validation;
+}
+
+LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(S32 track)
+{
+ static CycleTrack_t emptyTrack;
+ if (mDayTracks.size() <= track)
+ return emptyTrack;
+
+ return mDayTracks[track];
+}
+
+const LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrackConst(S32 track) const
+{
+ static CycleTrack_t emptyTrack;
+ if (mDayTracks.size() <= track)
+ return emptyTrack;
+
+ return mDayTracks[track];
+}
+
+bool LLSettingsDay::clearCycleTrack(S32 track)
+{
+ if ((track < 0) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to clear track (#" << track << ") out of range!" << LL_ENDL;
+ return false;
+ }
+ mDayTracks[track].clear();
+ clearAssetId();
+ setDirtyFlag(true);
+ return true;
+}
+
+bool LLSettingsDay::replaceCycleTrack(S32 track, const CycleTrack_t &source)
+{
+ if (source.empty())
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to copy an empty track." << LL_ENDL;
+ return false;
+ }
+
+ {
+ LLSettingsBase::ptr_t first((*source.begin()).second);
+ std::string setting_type = first->getSettingsType();
+
+ if (((setting_type == "water") && (track != 0)) ||
+ ((setting_type == "sky") && (track == 0)))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to copy track missmatch" << LL_ENDL;
+ return false;
+ }
+ }
+
+ if (!clearCycleTrack(track))
+ return false;
+
+ mDayTracks[track] = source;
+ return true;
+}
+
+
+bool LLSettingsDay::isTrackEmpty(S32 track) const
+{
+ if ((track < 0) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to test track (#" << track << ") out of range!" << LL_ENDL;
+ return true;
+ }
+
+ return mDayTracks[track].empty();
+}
+
+//=========================================================================
+void LLSettingsDay::startDayCycle()
+{
+ if (!mInitialized)
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to start day cycle on uninitialized object." << LL_ENDL;
+ return;
+ }
+}
+
+
+void LLSettingsDay::updateSettings()
+{
+}
+
+//=========================================================================
+LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno)
+{
+ if ((trackno < 0) || (trackno >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
+ return KeyframeList_t();
+ }
+
+ KeyframeList_t keyframes;
+ CycleTrack_t &track = mDayTracks[trackno];
+
+ keyframes.reserve(track.size());
+
+ for (CycleTrack_t::iterator it = track.begin(); it != track.end(); ++it)
+ {
+ keyframes.push_back((*it).first);
+ }
+
+ return keyframes;
+}
+
+bool LLSettingsDay::moveTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame)
+{
+ if ((trackno < 0) || (trackno >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
+ return false;
+ }
+
+ if (old_frame == new_frame)
+ {
+ return false;
+ }
+
+ CycleTrack_t &track = mDayTracks[trackno];
+ CycleTrack_t::iterator iter = track.find(old_frame);
+ if (iter != track.end())
+ {
+ LLSettingsBase::ptr_t base = iter->second;
+ track.erase(iter);
+ track[llclamp(new_frame, 0.0f, 1.0f)] = base;
+ track[new_frame] = base;
+ return true;
+ }
+
+ return false;
+
+}
+
+bool LLSettingsDay::removeTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& frame)
+{
+ if ((trackno < 0) || (trackno >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
+ return false;
+ }
+
+ CycleTrack_t &track = mDayTracks[trackno];
+ CycleTrack_t::iterator iter = track.find(frame);
+ if (iter != track.end())
+ {
+ LLSettingsBase::ptr_t base = iter->second;
+ track.erase(iter);
+ return true;
+ }
+
+ return false;
+}
+
+void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe)
+{
+ setSettingsAtKeyframe(water, keyframe, TRACK_WATER);
+}
+
+LLSettingsWater::ptr_t LLSettingsDay::getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const
+{
+ LLSettingsBase* p = getSettingsAtKeyframe(keyframe, TRACK_WATER).get();
+ return LLSettingsWater::ptr_t((LLSettingsWater*)p);
+}
+
+void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSky::ptr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track)
+{
+ if ((track < 1) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
+ return;
+ }
+
+ setSettingsAtKeyframe(sky, keyframe, track);
+}
+
+LLSettingsSky::ptr_t LLSettingsDay::getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
+{
+ if ((track < 1) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
+ return LLSettingsSky::ptr_t();
+ }
+
+ return PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(getSettingsAtKeyframe(keyframe, track));
+}
+
+void LLSettingsDay::setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track)
+{
+ if ((track < 0) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to set track (#" << track << ") out of range!" << LL_ENDL;
+ return;
+ }
+
+ std::string type = settings->getSettingsType();
+ if ((track == TRACK_WATER) && (type != "water"))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to water track!" << LL_ENDL;
+ llassert(type == "water");
+ return;
+ }
+ else if ((track != TRACK_WATER) && (type != "sky"))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to sky track!" << LL_ENDL;
+ llassert(type == "sky");
+ return;
+ }
+
+ mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = settings;
+ setDirtyFlag(true);
+}
+
+LLSettingsBase::ptr_t LLSettingsDay::getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
+{
+ if ((track < 0) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
+ return LLSettingsBase::ptr_t();
+ }
+
+ // todo: better way to identify keyframes?
+ CycleTrack_t::const_iterator iter = mDayTracks[track].find(keyframe);
+ if (iter != mDayTracks[track].end())
+ {
+ return iter->second;
+ }
+
+ return LLSettingsBase::ptr_t();
+}
+
+LLSettingsDay::CycleTrack_t::value_type LLSettingsDay::getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const
+{
+ if ((track < 0) || (track >= TRACK_MAX))
+ {
+ LL_WARNS("DAYCYCLE") << "Attempt to get track (#" << track << ") out of range!" << LL_ENDL;
+ return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
+ }
+
+ if (mDayTracks[track].empty())
+ {
+ LL_INFOS("DAYCYCLE") << "Empty track" << LL_ENDL;
+ return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
+ }
+
+ TrackPosition startframe(keyframe - fudge);
+ if (startframe < 0.0f)
+ startframe = 1.0f + startframe;
+
+ CycleTrack_t::iterator it = get_wrapping_atafter(const_cast<CycleTrack_t &>(mDayTracks[track]), startframe);
+
+ F32 dist = get_wrapping_distance(startframe, (*it).first);
+
+ //LL_DEBUGS("LAPRAS") << "[" << startframe << " ... " << keyframe << " -> " << (*it).first << "@" << dist << LL_ENDL;
+
+ if (dist <= (fudge * 2.0f))
+ return (*it);
+
+ return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
+}
+
+LLSettingsBase::TrackPosition LLSettingsDay::getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
+{
+ return get_wrapping_atafter(mDayTracks[track], keyframe)->first;
+}
+
+LLSettingsBase::TrackPosition LLSettingsDay::getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
+{
+ return get_wrapping_atbefore(mDayTracks[track], keyframe)->first;
+}
+
+LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe)
+{
+ return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe));
+}
+
+LLUUID LLSettingsDay::GetDefaultAssetId()
+{
+ return DEFAULT_ASSET_ID;
+}
+
+//=========================================================================
diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h
new file mode 100644
index 0000000000..8776f6725d
--- /dev/null
+++ b/indra/llinventory/llsettingsdaycycle.h
@@ -0,0 +1,156 @@
+/**
+* @file llsettingsdaycycle.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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_DAYCYCLE_H
+#define LL_SETTINGS_DAYCYCLE_H
+
+#include "llsettingsbase.h"
+
+class LLSettingsWater;
+class LLSettingsSky;
+
+// These are alias for LLSettingsWater::ptr_t and LLSettingsSky::ptr_t respectively.
+// Here for definitions only.
+typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> LLSettingsWaterPtr_t;
+typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> LLSettingsSkyPtr_t;
+
+class LLSettingsDay : public LLSettingsBase
+{
+public:
+ // 32-bit as LLSD only supports that width at present
+ typedef S32Seconds Seconds;
+
+ static const std::string SETTING_KEYID;
+ static const std::string SETTING_KEYNAME;
+ static const std::string SETTING_KEYKFRAME;
+ static const std::string SETTING_KEYHASH;
+ static const std::string SETTING_TRACKS;
+ static const std::string SETTING_FRAMES;
+
+ static const Seconds MINIMUM_DAYLENGTH;
+ static const Seconds DEFAULT_DAYLENGTH;
+ static const Seconds MAXIMUM_DAYLENGTH;
+
+ static const Seconds MINIMUM_DAYOFFSET;
+ static const Seconds DEFAULT_DAYOFFSET;
+ static const Seconds MAXIMUM_DAYOFFSET;
+
+ static const S32 TRACK_WATER;
+ static const S32 TRACK_GROUND_LEVEL;
+ static const S32 TRACK_MAX;
+ static const S32 FRAME_MAX;
+
+ static const F32 DEFAULT_FRAME_SLOP_FACTOR;
+
+ static const LLUUID DEFAULT_ASSET_ID;
+
+ typedef std::map<LLSettingsBase::TrackPosition, LLSettingsBase::ptr_t> CycleTrack_t;
+ typedef std::vector<CycleTrack_t> CycleList_t;
+ typedef PTR_NAMESPACE::shared_ptr<LLSettingsDay> ptr_t;
+ typedef PTR_NAMESPACE::weak_ptr<LLSettingsDay> wptr_t;
+ typedef std::vector<LLSettingsBase::TrackPosition> KeyframeList_t;
+ typedef std::pair<CycleTrack_t::iterator, CycleTrack_t::iterator> TrackBound_t;
+
+ //---------------------------------------------------------------------
+ LLSettingsDay(const LLSD &data);
+ virtual ~LLSettingsDay() { };
+
+ bool initialize(bool validate_frames = false);
+
+ virtual ptr_t buildClone() const = 0;
+ virtual ptr_t buildDeepCloneAndUncompress() const = 0;
+ virtual LLSD getSettings() const SETTINGS_OVERRIDE;
+ virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_DAYCYCLE; }
+
+
+ //---------------------------------------------------------------------
+ virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("daycycle"); }
+
+ // Settings status
+ virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE;
+
+ static LLSD defaults();
+
+ //---------------------------------------------------------------------
+ KeyframeList_t getTrackKeyframes(S32 track);
+ bool moveTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame);
+ bool removeTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& frame);
+
+ void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe);
+ LLSettingsWaterPtr_t getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const;
+ void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track);
+ LLSettingsSkyPtr_t getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
+ void setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track);
+ LLSettingsBase::ptr_t getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
+ CycleTrack_t::value_type getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const;
+
+ //---------------------------------------------------------------------
+ void startDayCycle();
+
+ virtual LLSettingsSkyPtr_t getDefaultSky() const = 0;
+ virtual LLSettingsWaterPtr_t getDefaultWater() const = 0;
+
+ virtual LLSettingsSkyPtr_t buildSky(LLSD) const = 0;
+ virtual LLSettingsWaterPtr_t buildWater(LLSD) const = 0;
+
+ void setInitialized(bool value = true) { mInitialized = value; }
+ CycleTrack_t & getCycleTrack(S32 track);
+ const CycleTrack_t & getCycleTrackConst(S32 track) const;
+ bool clearCycleTrack(S32 track);
+ bool replaceCycleTrack(S32 track, const CycleTrack_t &source);
+ bool isTrackEmpty(S32 track) const;
+
+ virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
+ static validation_list_t validationList();
+
+ virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
+
+ LLSettingsBase::TrackPosition getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
+ LLSettingsBase::TrackPosition getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
+
+ static LLUUID GetDefaultAssetId();
+
+protected:
+ LLSettingsDay();
+
+ virtual void updateSettings() SETTINGS_OVERRIDE;
+
+ bool mInitialized;
+
+private:
+ CycleList_t mDayTracks;
+
+ LLSettingsBase::Seconds mLastUpdateTime;
+
+ void parseFromLLSD(LLSD &data);
+
+ static CycleTrack_t::iterator getEntryAtOrBefore(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
+ static CycleTrack_t::iterator getEntryAtOrAfter(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
+ TrackBound_t getBoundingEntries(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
+};
+
+#endif
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
new file mode 100644
index 0000000000..4543f00454
--- /dev/null
+++ b/indra/llinventory/llsettingssky.cpp
@@ -0,0 +1,1460 @@
+/**
+* @file llsettingssky.cpp
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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 "llsettingssky.h"
+#include "indra_constants.h"
+#include <algorithm>
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "v3colorutil.h"
+
+//=========================================================================
+namespace {
+ const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees
+ const F32 NIGHTTIME_ELEVATION_SIN = (F32)sinf(NIGHTTIME_ELEVATION * DEG_TO_RAD);
+ const LLUUID IMG_BLOOM1("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef");
+}
+
+namespace {
+ LLQuaternion convert_azimuth_and_altitude_to_quat(F32 azimuth, F32 altitude)
+ {
+ F32 sinTheta = sin(azimuth);
+ F32 cosTheta = cos(azimuth);
+ F32 sinPhi = sin(altitude);
+ F32 cosPhi = cos(altitude);
+
+ LLVector3 dir;
+ // +x right, +z up, +y at...
+ dir.mV[0] = cosTheta * cosPhi;
+ dir.mV[1] = sinTheta * cosPhi;
+ dir.mV[2] = sinPhi;
+
+ LLVector3 axis = LLVector3::x_axis % dir;
+ axis.normalize();
+
+ F32 angle = acos(LLVector3::x_axis * dir);
+
+ LLQuaternion quat;
+ quat.setAngleAxis(angle, axis);
+
+ return quat;
+ }
+}
+
+static LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment");
+static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_SKYVALUES("Recalculate Sky");
+static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_BODIES("Recalculate Heavenly Bodies");
+static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_LIGHTING("Recalculate Lighting");
+
+//=========================================================================
+const std::string LLSettingsSky::SETTING_AMBIENT("ambient");
+const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density");
+const std::string LLSettingsSky::SETTING_BLUE_HORIZON("blue_horizon");
+const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier");
+const std::string LLSettingsSky::SETTING_DISTANCE_MULTIPLIER("distance_multiplier");
+const std::string LLSettingsSky::SETTING_HAZE_DENSITY("haze_density");
+const std::string LLSettingsSky::SETTING_HAZE_HORIZON("haze_horizon");
+
+const std::string LLSettingsSky::SETTING_BLOOM_TEXTUREID("bloom_id");
+const std::string LLSettingsSky::SETTING_CLOUD_COLOR("cloud_color");
+const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY1("cloud_pos_density1");
+const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY2("cloud_pos_density2");
+const std::string LLSettingsSky::SETTING_CLOUD_SCALE("cloud_scale");
+const std::string LLSettingsSky::SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate");
+const std::string LLSettingsSky::SETTING_CLOUD_SHADOW("cloud_shadow");
+const std::string LLSettingsSky::SETTING_CLOUD_TEXTUREID("cloud_id");
+
+const std::string LLSettingsSky::SETTING_DOME_OFFSET("dome_offset");
+const std::string LLSettingsSky::SETTING_DOME_RADIUS("dome_radius");
+const std::string LLSettingsSky::SETTING_GAMMA("gamma");
+const std::string LLSettingsSky::SETTING_GLOW("glow");
+
+const std::string LLSettingsSky::SETTING_LIGHT_NORMAL("lightnorm");
+const std::string LLSettingsSky::SETTING_MAX_Y("max_y");
+const std::string LLSettingsSky::SETTING_MOON_ROTATION("moon_rotation");
+const std::string LLSettingsSky::SETTING_MOON_SCALE("moon_scale");
+const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id");
+const std::string LLSettingsSky::SETTING_STAR_BRIGHTNESS("star_brightness");
+const std::string LLSettingsSky::SETTING_SUNLIGHT_COLOR("sunlight_color");
+const std::string LLSettingsSky::SETTING_SUN_ROTATION("sun_rotation");
+const std::string LLSettingsSky::SETTING_SUN_SCALE("sun_scale");
+const std::string LLSettingsSky::SETTING_SUN_TEXTUREID("sun_id");
+
+const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle");
+const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll");
+const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle");
+
+// these are new settings for the advanced atmospherics model
+const std::string LLSettingsSky::SETTING_PLANET_RADIUS("planet_radius");
+const std::string LLSettingsSky::SETTING_SKY_BOTTOM_RADIUS("sky_bottom_radius");
+const std::string LLSettingsSky::SETTING_SKY_TOP_RADIUS("sky_top_radius");
+const std::string LLSettingsSky::SETTING_SUN_ARC_RADIANS("sun_arc_radians");
+
+const std::string LLSettingsSky::SETTING_RAYLEIGH_CONFIG("rayleigh_config");
+const std::string LLSettingsSky::SETTING_MIE_CONFIG("mie_config");
+const std::string LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR("anisotropy");
+const std::string LLSettingsSky::SETTING_ABSORPTION_CONFIG("absorption_config");
+
+const std::string LLSettingsSky::KEY_DENSITY_PROFILE("density");
+const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH("width");
+const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM("exp_term");
+const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR("exp_scale");
+const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM("linear_term");
+const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM("constant_term");
+
+const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("ff64f04e-097f-40bc-9063-d8d48c308739");
+
+static const LLUUID DEFAULT_SUN_ID("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver
+static const LLUUID DEFAULT_MOON_ID("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver
+static const LLUUID DEFAULT_CLOUD_ID("1dc1368f-e8fe-f02d-a08d-9d9f11c1af6b");
+
+const std::string LLSettingsSky::SETTING_LEGACY_HAZE("legacy_haze");
+
+const F32 LLSettingsSky::DOME_OFFSET(0.96f);
+const F32 LLSettingsSky::DOME_RADIUS(15000.f);
+
+namespace
+{
+
+LLSettingsSky::validation_list_t legacyHazeValidationList()
+{
+ static LLSettingsBase::validation_list_t legacyHazeValidation;
+ if (legacyHazeValidation.empty())
+ {
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4.0f)))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(0.9f)))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(100.0f)))));
+ }
+ return legacyHazeValidation;
+}
+
+LLSettingsSky::validation_list_t rayleighValidationList()
+{
+ static LLSettingsBase::validation_list_t rayleighValidation;
+ if (rayleighValidation.empty())
+ {
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f)))));
+
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f)))));
+
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ }
+ return rayleighValidation;
+}
+
+LLSettingsSky::validation_list_t absorptionValidationList()
+{
+ static LLSettingsBase::validation_list_t absorptionValidation;
+ if (absorptionValidation.empty())
+ {
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f)))));
+
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f)))));
+
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ }
+ return absorptionValidation;
+}
+
+LLSettingsSky::validation_list_t mieValidationList()
+{
+ static LLSettingsBase::validation_list_t mieValidation;
+ if (mieValidation.empty())
+ {
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f)))));
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f)))));
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ }
+ return mieValidation;
+}
+
+bool validateLegacyHaze(LLSD &value)
+{
+ LLSettingsSky::validation_list_t legacyHazeValidations = legacyHazeValidationList();
+ llassert(value.type() == LLSD::TypeMap);
+ LLSD result = LLSettingsBase::settingValidation(value, legacyHazeValidations);
+ if (result["errors"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Legacy Haze Config Validation errors: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ if (result["warnings"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Legacy Haze Config Validation warnings: " << result["warnings"] << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+bool validateRayleighLayers(LLSD &value)
+{
+ LLSettingsSky::validation_list_t rayleighValidations = rayleighValidationList();
+ if (value.isArray())
+ {
+ bool allGood = true;
+ for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf)
+ {
+ LLSD& layerConfig = (*itf);
+ if (layerConfig.type() == LLSD::TypeMap)
+ {
+ if (!validateRayleighLayers(layerConfig))
+ {
+ allGood = false;
+ }
+ }
+ else if (layerConfig.type() == LLSD::TypeArray)
+ {
+ return validateRayleighLayers(layerConfig);
+ }
+ else
+ {
+ return LLSettingsBase::settingValidation(value, rayleighValidations);
+ }
+ }
+ return allGood;
+ }
+ llassert(value.type() == LLSD::TypeMap);
+ LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations);
+ if (result["errors"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Rayleigh Config Validation errors: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ if (result["warnings"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Rayleigh Config Validation warnings: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+bool validateAbsorptionLayers(LLSD &value)
+{
+ LLSettingsBase::validation_list_t absorptionValidations = absorptionValidationList();
+ if (value.isArray())
+ {
+ bool allGood = true;
+ for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf)
+ {
+ LLSD& layerConfig = (*itf);
+ if (layerConfig.type() == LLSD::TypeMap)
+ {
+ if (!validateAbsorptionLayers(layerConfig))
+ {
+ allGood = false;
+ }
+ }
+ else if (layerConfig.type() == LLSD::TypeArray)
+ {
+ return validateAbsorptionLayers(layerConfig);
+ }
+ else
+ {
+ return LLSettingsBase::settingValidation(value, absorptionValidations);
+ }
+ }
+ return allGood;
+ }
+ llassert(value.type() == LLSD::TypeMap);
+ LLSD result = LLSettingsBase::settingValidation(value, absorptionValidations);
+ if (result["errors"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Absorption Config Validation errors: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ if (result["warnings"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Absorption Config Validation warnings: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+bool validateMieLayers(LLSD &value)
+{
+ LLSettingsBase::validation_list_t mieValidations = mieValidationList();
+ if (value.isArray())
+ {
+ bool allGood = true;
+ for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf)
+ {
+ LLSD& layerConfig = (*itf);
+ if (layerConfig.type() == LLSD::TypeMap)
+ {
+ if (!validateMieLayers(layerConfig))
+ {
+ allGood = false;
+ }
+ }
+ else if (layerConfig.type() == LLSD::TypeArray)
+ {
+ return validateMieLayers(layerConfig);
+ }
+ else
+ {
+ return LLSettingsBase::settingValidation(value, mieValidations);
+ }
+ }
+ return allGood;
+ }
+ LLSD result = LLSettingsBase::settingValidation(value, mieValidations);
+ if (result["errors"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Mie Config Validation errors: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ if (result["warnings"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Mie Config Validation warnings: " << result["warnings"] << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+}
+
+//=========================================================================
+LLSettingsSky::LLSettingsSky(const LLSD &data) :
+ LLSettingsBase(data),
+ mNextSunTextureId(),
+ mNextMoonTextureId(),
+ mNextCloudTextureId(),
+ mNextBloomTextureId()
+{
+}
+
+LLSettingsSky::LLSettingsSky():
+ LLSettingsBase(),
+ mNextSunTextureId(),
+ mNextMoonTextureId(),
+ mNextCloudTextureId(),
+ mNextBloomTextureId()
+{
+}
+
+void LLSettingsSky::replaceSettings(LLSD settings)
+{
+ LLSettingsBase::replaceSettings(settings);
+ mNextSunTextureId.setNull();
+ mNextMoonTextureId.setNull();
+ mNextCloudTextureId.setNull();
+ mNextBloomTextureId.setNull();
+}
+
+void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
+{
+ llassert(getSettingsType() == end->getSettingsType());
+
+ LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(end);
+ if (other)
+ {
+ LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf);
+ replaceSettings(blenddata);
+ mNextSunTextureId = other->getSunTextureId();
+ mNextMoonTextureId = other->getMoonTextureId();
+ mNextCloudTextureId = other->getCloudNoiseTextureId();
+ mNextBloomTextureId = other->getBloomTextureId();
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "Could not cast end settings to sky. No blend performed." << LL_ENDL;
+ }
+
+ setBlendFactor(blendf);
+}
+
+LLSettingsSky::stringset_t LLSettingsSky::getSkipInterpolateKeys() const
+{
+ static stringset_t skipSet;
+
+ if (skipSet.empty())
+ {
+ skipSet = LLSettingsBase::getSkipInterpolateKeys();
+ skipSet.insert(SETTING_RAYLEIGH_CONFIG);
+ skipSet.insert(SETTING_MIE_CONFIG);
+ skipSet.insert(SETTING_ABSORPTION_CONFIG);
+ }
+
+ return skipSet;
+}
+
+LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const
+{
+ static stringset_t slepSet;
+
+ if (slepSet.empty())
+ {
+ slepSet.insert(SETTING_SUN_ROTATION);
+ slepSet.insert(SETTING_MOON_ROTATION);
+ }
+
+ return slepSet;
+}
+
+LLSettingsSky::validation_list_t LLSettingsSky::getValidationList() const
+{
+ return LLSettingsSky::validationList();
+}
+
+LLSettingsSky::validation_list_t LLSettingsSky::validationList()
+{
+ static validation_list_t validation;
+
+ if (validation.empty())
+ { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
+ // copy constructor for LLSDArray. Directly binding the LLSDArray as
+ // a parameter without first wrapping it in a pure LLSD object will result
+ // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
+ validation.push_back(Validator(SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+ validation.push_back(Validator(SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+ validation.push_back(Validator(SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
+ validation.push_back(Validator(SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
+ validation.push_back(Validator(SETTING_AMBIENT, false, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ validation.push_back(Validator(SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ validation.push_back(Validator(SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1000.0f)))));
+
+
+ validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(1.0f)(1.0f)(3.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.001f)(3.0f)))));
+ validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(-50.0f)(-50.0f)),
+ LLSD(LLSDArray(50.0f)(50.0f)))));
+ validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID));
+
+ validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(2000.0f)))));
+ validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
+ validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.2f)("*")(-10.0f)("*")),
+ LLSD(LLSDArray(40.0f)("*")(10.0f)("*")))));
+
+ validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(10000.0f)))));
+ validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
+ validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(500.0f)))));
+ validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
+ validation.push_back(Validator(SETTING_SUN_SCALE, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID));
+
+ validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+
+ validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+
+ validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+
+ validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.1f)))));
+
+ validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
+ validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
+ validation.push_back(Validator(SETTING_MIE_CONFIG, true, LLSD::TypeArray, &validateMieLayers));
+ validation.push_back(Validator(SETTING_LEGACY_HAZE, false, LLSD::TypeMap, &validateLegacyHaze));
+ }
+ return validation;
+}
+
+LLSD LLSettingsSky::createDensityProfileLayer(
+ F32 width,
+ F32 exponential_term,
+ F32 exponential_scale_factor,
+ F32 linear_term,
+ F32 constant_term,
+ F32 aniso_factor)
+{
+ LLSD dflt_layer;
+ dflt_layer[SETTING_DENSITY_PROFILE_WIDTH] = width; // 0 -> the entire atmosphere
+ dflt_layer[SETTING_DENSITY_PROFILE_EXP_TERM] = exponential_term;
+ dflt_layer[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = exponential_scale_factor;
+ dflt_layer[SETTING_DENSITY_PROFILE_LINEAR_TERM] = linear_term;
+ dflt_layer[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = constant_term;
+
+ if (aniso_factor != 0.0f)
+ {
+ dflt_layer[SETTING_MIE_ANISOTROPY_FACTOR] = aniso_factor;
+ }
+
+ return dflt_layer;
+}
+
+LLSD LLSettingsSky::createSingleLayerDensityProfile(
+ F32 width,
+ F32 exponential_term,
+ F32 exponential_scale_factor,
+ F32 linear_term,
+ F32 constant_term,
+ F32 aniso_factor)
+{
+ LLSD dflt;
+ LLSD dflt_layer = createDensityProfileLayer(width, exponential_term, exponential_scale_factor, linear_term, constant_term, aniso_factor);
+ dflt.append(dflt_layer);
+ return dflt;
+}
+
+LLSD LLSettingsSky::rayleighConfigDefault()
+{
+ return createSingleLayerDensityProfile(0.0f, 1.0f, -1.0f / 8000.0f, 0.0f, 0.0f);
+}
+
+LLSD LLSettingsSky::absorptionConfigDefault()
+{
+// absorption (ozone) has two linear ramping zones
+ LLSD dflt_absorption_layer_a = createDensityProfileLayer(25000.0f, 0.0f, 0.0f, -1.0f / 25000.0f, -2.0f / 3.0f);
+ LLSD dflt_absorption_layer_b = createDensityProfileLayer(0.0f, 0.0f, 0.0f, -1.0f / 15000.0f, 8.0f / 3.0f);
+ LLSD dflt_absorption;
+ dflt_absorption.append(dflt_absorption_layer_a);
+ dflt_absorption.append(dflt_absorption_layer_b);
+ return dflt_absorption;
+}
+
+LLSD LLSettingsSky::mieConfigDefault()
+{
+ LLSD dflt_mie = createSingleLayerDensityProfile(0.0f, 1.0f, -1.0f / 1200.0f, 0.0f, 0.0f, 0.8f);
+ return dflt_mie;
+}
+
+LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
+{
+ static LLSD dfltsetting;
+
+ if (dfltsetting.size() == 0)
+ {
+ LLQuaternion sunquat;
+ LLQuaternion moonquat;
+
+ F32 azimuth = (F_PI * position) + (80.0f * DEG_TO_RAD);
+ F32 altitude = (F_PI * position);
+
+ // give the sun and moon slightly different tracks through the sky
+ // instead of positioning them at opposite poles from each other...
+ sunquat = convert_azimuth_and_altitude_to_quat(altitude, azimuth);
+ moonquat = convert_azimuth_and_altitude_to_quat(altitude + (F_PI * 0.125f), azimuth + (F_PI * 0.125f));
+
+ // Magic constants copied form dfltsetting.xml
+ dfltsetting[SETTING_CLOUD_COLOR] = LLColor4(0.4099, 0.4099, 0.4099, 0.0).getValue();
+ dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue();
+ dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue();
+ dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199);
+ dfltsetting[SETTING_CLOUD_SCROLL_RATE] = LLSDArray(0.0f)(0.0f);
+ dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699);
+
+ dfltsetting[SETTING_DOME_OFFSET] = LLSD::Real(0.96f);
+ dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f);
+ dfltsetting[SETTING_GAMMA] = LLSD::Real(1.0);
+ dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue();
+
+ dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605);
+ dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue();
+ dfltsetting[SETTING_STAR_BRIGHTNESS] = LLSD::Real(256.0000);
+ dfltsetting[SETTING_SUNLIGHT_COLOR] = LLColor4(0.7342, 0.7815, 0.8999, 0.0).getValue();
+ dfltsetting[SETTING_SUN_ROTATION] = sunquat.getValue();
+
+ dfltsetting[SETTING_BLOOM_TEXTUREID] = GetDefaultBloomTextureId();
+ dfltsetting[SETTING_CLOUD_TEXTUREID] = GetDefaultCloudNoiseTextureId();
+ dfltsetting[SETTING_MOON_TEXTUREID] = GetDefaultMoonTextureId();
+ dfltsetting[SETTING_SUN_TEXTUREID] = GetDefaultSunTextureId();
+
+ dfltsetting[SETTING_TYPE] = "sky";
+
+ // defaults are for earth...
+ dfltsetting[SETTING_PLANET_RADIUS] = 6360.0f;
+ dfltsetting[SETTING_SKY_BOTTOM_RADIUS] = 6360.0f;
+ dfltsetting[SETTING_SKY_TOP_RADIUS] = 6420.0f;
+ dfltsetting[SETTING_SUN_ARC_RADIANS] = 0.00045f;
+
+ dfltsetting[SETTING_RAYLEIGH_CONFIG] = rayleighConfigDefault();
+ dfltsetting[SETTING_MIE_CONFIG] = mieConfigDefault();
+ dfltsetting[SETTING_ABSORPTION_CONFIG] = absorptionConfigDefault();
+ }
+
+ return dfltsetting;
+}
+
+LLSD LLSettingsSky::translateLegacyHazeSettings(const LLSD& legacy)
+{
+ LLSD legacyhazesettings;
+
+// AdvancedAtmospherics TODO
+// These need to be translated into density profile info in the new settings format...
+// LEGACY_ATMOSPHERICS
+ if (legacy.has(SETTING_BLUE_DENSITY))
+ {
+ legacyhazesettings[SETTING_BLUE_DENSITY] = LLColor3(legacy[SETTING_BLUE_DENSITY]).getValue();
+ }
+ if (legacy.has(SETTING_BLUE_HORIZON))
+ {
+ legacyhazesettings[SETTING_BLUE_HORIZON] = LLColor3(legacy[SETTING_BLUE_HORIZON]).getValue();
+ }
+ if (legacy.has(SETTING_DENSITY_MULTIPLIER))
+ {
+ legacyhazesettings[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(legacy[SETTING_DENSITY_MULTIPLIER][0].asReal());
+ }
+ if (legacy.has(SETTING_DISTANCE_MULTIPLIER))
+ {
+ legacyhazesettings[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(legacy[SETTING_DISTANCE_MULTIPLIER][0].asReal());
+ }
+ if (legacy.has(SETTING_HAZE_DENSITY))
+ {
+ legacyhazesettings[SETTING_HAZE_DENSITY] = LLSD::Real(legacy[SETTING_HAZE_DENSITY][0].asReal());
+ }
+ if (legacy.has(SETTING_HAZE_HORIZON))
+ {
+ legacyhazesettings[SETTING_HAZE_HORIZON] = LLSD::Real(legacy[SETTING_HAZE_HORIZON][0].asReal());
+ }
+
+ return legacyhazesettings;
+}
+
+LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)
+{
+ LLSD newsettings(defaults());
+
+ // Move legacy haze parameters to an inner map
+ // allowing backward compat and simple conversion to legacy format
+ LLSD legacyhazesettings;
+ legacyhazesettings = translateLegacyHazeSettings(legacy);
+ if (legacyhazesettings.size() > 0)
+ {
+ newsettings[SETTING_LEGACY_HAZE] = legacyhazesettings;
+ }
+
+ if (legacy.has(SETTING_AMBIENT))
+ {
+ newsettings[SETTING_AMBIENT] = LLColor3(legacy[SETTING_AMBIENT]).getValue();
+ }
+ if (legacy.has(SETTING_CLOUD_COLOR))
+ {
+ newsettings[SETTING_CLOUD_COLOR] = LLColor3(legacy[SETTING_CLOUD_COLOR]).getValue();
+ }
+ if (legacy.has(SETTING_CLOUD_POS_DENSITY1))
+ {
+ newsettings[SETTING_CLOUD_POS_DENSITY1] = LLColor3(legacy[SETTING_CLOUD_POS_DENSITY1]).getValue();
+ }
+ if (legacy.has(SETTING_CLOUD_POS_DENSITY2))
+ {
+ newsettings[SETTING_CLOUD_POS_DENSITY2] = LLColor3(legacy[SETTING_CLOUD_POS_DENSITY2]).getValue();
+ }
+ if (legacy.has(SETTING_CLOUD_SCALE))
+ {
+ newsettings[SETTING_CLOUD_SCALE] = LLSD::Real(legacy[SETTING_CLOUD_SCALE][0].asReal());
+ }
+ if (legacy.has(SETTING_CLOUD_SCROLL_RATE))
+ {
+ LLVector2 cloud_scroll(legacy[SETTING_CLOUD_SCROLL_RATE]);
+
+ cloud_scroll -= LLVector2(10, 10);
+ if (legacy.has(SETTING_LEGACY_ENABLE_CLOUD_SCROLL))
+ {
+ LLSD enabled = legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL];
+ if (!enabled[0].asBoolean())
+ cloud_scroll.mV[0] = 0.0f;
+ if (!enabled[1].asBoolean())
+ cloud_scroll.mV[1] = 0.0f;
+ }
+
+ newsettings[SETTING_CLOUD_SCROLL_RATE] = cloud_scroll.getValue();
+ }
+ if (legacy.has(SETTING_CLOUD_SHADOW))
+ {
+ newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(legacy[SETTING_CLOUD_SHADOW][0].asReal());
+ }
+
+
+ if (legacy.has(SETTING_GAMMA))
+ {
+ newsettings[SETTING_GAMMA] = legacy[SETTING_GAMMA][0].asReal();
+ }
+ if (legacy.has(SETTING_GLOW))
+ {
+ newsettings[SETTING_GLOW] = LLColor3(legacy[SETTING_GLOW]).getValue();
+ }
+
+ if (legacy.has(SETTING_MAX_Y))
+ {
+ newsettings[SETTING_MAX_Y] = LLSD::Real(legacy[SETTING_MAX_Y][0].asReal());
+ }
+ if (legacy.has(SETTING_STAR_BRIGHTNESS))
+ {
+ newsettings[SETTING_STAR_BRIGHTNESS] = LLSD::Real(legacy[SETTING_STAR_BRIGHTNESS].asReal() * 250.0f);
+ }
+ if (legacy.has(SETTING_SUNLIGHT_COLOR))
+ {
+ newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(legacy[SETTING_SUNLIGHT_COLOR]).getValue();
+ }
+
+ if (legacy.has(SETTING_PLANET_RADIUS))
+ {
+ newsettings[SETTING_PLANET_RADIUS] = LLSD::Real(legacy[SETTING_PLANET_RADIUS].asReal());
+ }
+
+ if (legacy.has(SETTING_SKY_BOTTOM_RADIUS))
+ {
+ newsettings[SETTING_SKY_BOTTOM_RADIUS] = LLSD::Real(legacy[SETTING_SKY_BOTTOM_RADIUS].asReal());
+ }
+
+ if (legacy.has(SETTING_SKY_TOP_RADIUS))
+ {
+ newsettings[SETTING_SKY_TOP_RADIUS] = LLSD::Real(legacy[SETTING_SKY_TOP_RADIUS].asReal());
+ }
+
+ if (legacy.has(SETTING_SUN_ARC_RADIANS))
+ {
+ newsettings[SETTING_SUN_ARC_RADIANS] = LLSD::Real(legacy[SETTING_SUN_ARC_RADIANS].asReal());
+ }
+
+ if (legacy.has(SETTING_LEGACY_EAST_ANGLE) && legacy.has(SETTING_LEGACY_SUN_ANGLE))
+ {
+ // get counter-clockwise radian angle from clockwise legacy WL east angle...
+ F32 azimuth = -legacy[SETTING_LEGACY_EAST_ANGLE].asReal();
+ F32 altitude = legacy[SETTING_LEGACY_SUN_ANGLE].asReal();
+
+ LLQuaternion sunquat = convert_azimuth_and_altitude_to_quat(azimuth, altitude);
+ // original WL moon dir was diametrically opposed to the sun dir
+ LLQuaternion moonquat = convert_azimuth_and_altitude_to_quat(azimuth + F_PI, -altitude);
+
+ newsettings[SETTING_SUN_ROTATION] = sunquat.getValue();
+ newsettings[SETTING_MOON_ROTATION] = moonquat.getValue();
+ }
+
+ return newsettings;
+}
+
+void LLSettingsSky::updateSettings()
+{
+ LL_RECORD_BLOCK_TIME(FTM_RECALCULATE_SKYVALUES);
+
+ // base class clears dirty flag so as to not trigger recursive update
+ LLSettingsBase::updateSettings();
+
+ // NOTE: these functions are designed to do nothing unless a dirty bit has been set
+ // so if you add new settings that are referenced by these update functions,
+ // you'll need to insure that your setter updates the dirty bits as well
+ calculateHeavenlyBodyPositions();
+ calculateLightSettings();
+}
+
+bool LLSettingsSky::getIsSunUp() const
+{
+ LLVector3 sunDir = getSunDirection();
+ return sunDir.mV[2] > NIGHTTIME_ELEVATION_SIN;
+}
+
+bool LLSettingsSky::getIsMoonUp() const
+{
+ LLVector3 moonDir = getMoonDirection();
+ return moonDir.mV[2] > NIGHTTIME_ELEVATION_SIN;
+}
+
+void LLSettingsSky::calculateHeavenlyBodyPositions() const
+{
+ LLQuaternion sunq = getSunRotation();
+ LLQuaternion moonq = getMoonRotation();
+
+ mSunDirection = LLVector3::x_axis * sunq;
+ mMoonDirection = LLVector3::x_axis * moonq;
+
+ mSunDirection.normalize();
+ mMoonDirection.normalize();
+
+ //LL_WARNS("LAPRAS") << "Sun info: Rotation=" << sunq << " Vector=" << mSunDirection << LL_ENDL;
+ //LL_WARNS("LAPRAS") << "Moon info: Rotation=" << moonq << " Vector=" << mMoonDirection << LL_ENDL;
+
+ if (mSunDirection.lengthSquared() < 0.01f)
+ LL_WARNS("SETTINGS") << "Zero length sun direction. Wailing and gnashing of teeth may follow... or not." << LL_ENDL;
+ if (mMoonDirection.lengthSquared() < 0.01f)
+ LL_WARNS("SETTINGS") << "Zero length moon direction. Wailing and gnashing of teeth may follow... or not." << LL_ENDL;
+
+ llassert(mSunDirection.lengthSquared() > 0.01f);
+ llassert(mMoonDirection.lengthSquared() > 0.01f);
+}
+
+LLVector3 LLSettingsSky::getLightDirection() const
+{
+ update();
+
+ // is the normal from the sun or the moon
+ if (getIsSunUp())
+ {
+ return mSunDirection;
+ }
+ else if (getIsMoonUp())
+ {
+ return mMoonDirection;
+ }
+
+ return LLVector3::z_axis;
+}
+
+LLColor3 LLSettingsSky::getBlueDensity() const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_BLUE_DENSITY))
+ {
+ return LLColor3(mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_DENSITY]);
+ }
+ return LLColor3(0.2447f, 0.4487f, 0.7599f);
+}
+
+LLColor3 LLSettingsSky::getBlueHorizon() const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_BLUE_HORIZON))
+ {
+ return LLColor3(mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_HORIZON]);
+ }
+ return LLColor3(0.4954f, 0.4954f, 0.6399f);
+}
+
+F32 LLSettingsSky::getHazeDensity() const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_HAZE_DENSITY))
+ {
+ return mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_DENSITY].asReal();
+ }
+ return 0.7f;
+}
+
+F32 LLSettingsSky::getHazeHorizon() const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_HAZE_HORIZON))
+ {
+ return mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_HORIZON].asReal();
+ }
+ return 0.19f;
+}
+
+F32 LLSettingsSky::getDensityMultiplier() const
+{
+ F32 density_multiplier = 0.0001f;
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_DENSITY_MULTIPLIER))
+ {
+ density_multiplier = mSettings[SETTING_LEGACY_HAZE][SETTING_DENSITY_MULTIPLIER].asReal();
+ }
+ return density_multiplier;
+}
+
+F32 LLSettingsSky::getDistanceMultiplier() const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_DISTANCE_MULTIPLIER))
+ {
+ return mSettings[SETTING_LEGACY_HAZE][SETTING_DISTANCE_MULTIPLIER].asReal();
+ }
+ return 0.8f;
+}
+
+void LLSettingsSky::setBlueDensity(const LLColor3 &val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_DENSITY] = val.getValue();
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setBlueHorizon(const LLColor3 &val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_HORIZON] = val.getValue();
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setDensityMultiplier(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_DENSITY_MULTIPLIER] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setDistanceMultiplier(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_DISTANCE_MULTIPLIER] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setHazeDensity(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_DENSITY] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setHazeHorizon(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_HORIZON] = val;
+ setDirtyFlag(true);
+}
+
+// Sunlight attenuation effect (hue and brightness) due to atmosphere
+// this is used later for sunlight modulation at various altitudes
+LLColor3 LLSettingsSky::getLightAttenuation(F32 distance) const
+{
+// LEGACY_ATMOSPHERICS
+ LLColor3 blue_density = getBlueDensity();
+ F32 haze_density = getHazeDensity();
+ F32 density_multiplier = getDensityMultiplier();
+ LLColor3 density = (blue_density * 1.0 + smear(haze_density * 0.25f));
+ LLColor3 light_atten = density * density_multiplier * distance;
+ return light_atten;
+}
+
+LLColor3 LLSettingsSky::getLightTransmittance() const
+{
+// LEGACY_ATMOSPHERICS
+ LLColor3 blue_density = getBlueDensity();
+ F32 haze_density = getHazeDensity();
+ F32 density_multiplier = getDensityMultiplier();
+ LLColor3 temp1 = blue_density + smear(haze_density);
+ // Transparency (-> temp1)
+ temp1 = componentExp((temp1 * -1.f) * density_multiplier);
+ return temp1;
+}
+
+LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in) const
+{
+ F32 gamma = getGamma();
+ LLColor3 v(in);
+ v.clamp();
+ v= smear(1.0f) - v;
+ v = componentPow(v, gamma);
+ v = smear(1.0f) - v;
+ return v;
+}
+
+LLVector3 LLSettingsSky::getSunDirection() const
+{
+ update();
+ return mSunDirection;
+}
+
+LLVector3 LLSettingsSky::getMoonDirection() const
+{
+ update();
+ return mMoonDirection;
+}
+
+LLColor4U LLSettingsSky::getFadeColor() const
+{
+ update();
+ return mFadeColor;
+}
+
+LLColor4 LLSettingsSky::getMoonAmbient() const
+{
+ update();
+ return mMoonAmbient;
+}
+
+LLColor3 LLSettingsSky::getMoonDiffuse() const
+{
+ update();
+ return mMoonDiffuse;
+}
+
+LLColor4 LLSettingsSky::getSunAmbient() const
+{
+ update();
+ return mSunAmbient;
+}
+
+LLColor3 LLSettingsSky::getSunDiffuse() const
+{
+ update();
+ return mSunDiffuse;
+}
+
+LLColor4 LLSettingsSky::getTotalAmbient() const
+{
+ update();
+ return mTotalAmbient;
+}
+
+void LLSettingsSky::calculateLightSettings() const
+{
+ // Initialize temp variables
+ LLColor3 sunlight = getSunlightColor();
+ LLColor3 ambient = getAmbientColor();
+ F32 cloud_shadow = getCloudShadow();
+ LLVector3 lightnorm = getLightDirection();
+
+ // Sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ F32 max_y = getMaxY();
+ LLColor3 light_atten = getLightAttenuation(max_y);
+ LLColor3 light_transmittance = getLightTransmittance();
+
+ // and vary_sunlight will work properly with moon light
+ F32 lighty = lightnorm[1];
+
+ lighty = llmax(0.f, lighty);
+ if(lighty > 0.f)
+ {
+ lighty = 1.f / lighty;
+ }
+ componentMultBy(sunlight, componentExp((light_atten * -1.f) * lighty));
+
+ //increase ambient when there are more clouds
+ LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f;
+
+ //brightness of surface both sunlight and ambient
+ mSunDiffuse = gammaCorrect(componentMult(sunlight, light_transmittance));
+ mSunAmbient = gammaCorrect(componentMult(tmpAmbient, light_transmittance) * 0.5);
+
+ mMoonDiffuse = gammaCorrect(componentMult(LLColor3::white, light_transmittance));
+ mMoonAmbient = gammaCorrect(componentMult(LLColor3::white, light_transmittance) * 0.5f);
+ mTotalAmbient = mSunAmbient;
+
+ mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
+ mFadeColor.setAlpha(0);
+}
+
+LLUUID LLSettingsSky::GetDefaultAssetId()
+{
+ return DEFAULT_ASSET_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultSunTextureId()
+{
+ return LLUUID::null;
+}
+
+
+LLUUID LLSettingsSky::GetBlankSunTextureId()
+{
+ return DEFAULT_SUN_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultMoonTextureId()
+{
+ return DEFAULT_MOON_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultCloudNoiseTextureId()
+{
+ return DEFAULT_CLOUD_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultBloomTextureId()
+{
+ return IMG_BLOOM1;
+}
+
+F32 LLSettingsSky::getPlanetRadius() const
+{
+ return mSettings[SETTING_PLANET_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSkyBottomRadius() const
+{
+ return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSkyTopRadius() const
+{
+ return mSettings[SETTING_SKY_TOP_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSunArcRadians() const
+{
+ return mSettings[SETTING_SUN_ARC_RADIANS].asReal();
+}
+
+F32 LLSettingsSky::getMieAnisotropy() const
+{
+ return getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal();
+}
+
+LLSD LLSettingsSky::getRayleighConfig() const
+{
+ LLSD copy = *(mSettings[SETTING_RAYLEIGH_CONFIG].beginArray());
+ return copy;
+}
+
+LLSD LLSettingsSky::getMieConfig() const
+{
+ LLSD copy = *(mSettings[SETTING_MIE_CONFIG].beginArray());
+ return copy;
+}
+
+LLSD LLSettingsSky::getAbsorptionConfig() const
+{
+ LLSD copy = *(mSettings[SETTING_ABSORPTION_CONFIG].beginArray());
+ return copy;
+}
+
+LLSD LLSettingsSky::getRayleighConfigs() const
+{
+ return mSettings[SETTING_RAYLEIGH_CONFIG];
+}
+
+LLSD LLSettingsSky::getMieConfigs() const
+{
+ return mSettings[SETTING_MIE_CONFIG];
+}
+
+LLSD LLSettingsSky::getAbsorptionConfigs() const
+{
+ return mSettings[SETTING_ABSORPTION_CONFIG];
+}
+
+void LLSettingsSky::setRayleighConfigs(const LLSD& rayleighConfig)
+{
+ mSettings[SETTING_RAYLEIGH_CONFIG] = rayleighConfig;
+}
+
+void LLSettingsSky::setMieConfigs(const LLSD& mieConfig)
+{
+ mSettings[SETTING_MIE_CONFIG] = mieConfig;
+}
+
+void LLSettingsSky::setAbsorptionConfigs(const LLSD& absorptionConfig)
+{
+ mSettings[SETTING_ABSORPTION_CONFIG] = absorptionConfig;
+}
+
+LLUUID LLSettingsSky::getBloomTextureId() const
+{
+ return mSettings[SETTING_BLOOM_TEXTUREID].asUUID();
+}
+
+//---------------------------------------------------------------------
+LLColor3 LLSettingsSky::getAmbientColor() const
+{
+ return LLColor3(mSettings[SETTING_AMBIENT]);
+}
+
+void LLSettingsSky::setAmbientColor(const LLColor3 &val)
+{
+ setValue(SETTING_AMBIENT, val);
+}
+
+LLColor3 LLSettingsSky::getCloudColor() const
+{
+ return LLColor3(mSettings[SETTING_CLOUD_COLOR]);
+}
+
+void LLSettingsSky::setCloudColor(const LLColor3 &val)
+{
+ setValue(SETTING_CLOUD_COLOR, val);
+}
+
+LLUUID LLSettingsSky::getCloudNoiseTextureId() const
+{
+ return mSettings[SETTING_CLOUD_TEXTUREID].asUUID();
+}
+
+void LLSettingsSky::setCloudNoiseTextureId(const LLUUID &id)
+{
+ setValue(SETTING_CLOUD_TEXTUREID, id);
+}
+
+LLColor3 LLSettingsSky::getCloudPosDensity1() const
+{
+ return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY1]);
+}
+
+void LLSettingsSky::setCloudPosDensity1(const LLColor3 &val)
+{
+ setValue(SETTING_CLOUD_POS_DENSITY1, val);
+}
+
+LLColor3 LLSettingsSky::getCloudPosDensity2() const
+{
+ return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY2]);
+}
+
+void LLSettingsSky::setCloudPosDensity2(const LLColor3 &val)
+{
+ setValue(SETTING_CLOUD_POS_DENSITY2, val);
+}
+
+F32 LLSettingsSky::getCloudScale() const
+{
+ return mSettings[SETTING_CLOUD_SCALE].asReal();
+}
+
+void LLSettingsSky::setCloudScale(F32 val)
+{
+ setValue(SETTING_CLOUD_SCALE, val);
+}
+
+LLVector2 LLSettingsSky::getCloudScrollRate() const
+{
+ return LLVector2(mSettings[SETTING_CLOUD_SCROLL_RATE]);
+}
+
+void LLSettingsSky::setCloudScrollRate(const LLVector2 &val)
+{
+ setValue(SETTING_CLOUD_SCROLL_RATE, val);
+}
+
+void LLSettingsSky::setCloudScrollRateX(F32 val)
+{
+ mSettings[SETTING_CLOUD_SCROLL_RATE][0] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setCloudScrollRateY(F32 val)
+{
+ mSettings[SETTING_CLOUD_SCROLL_RATE][1] = val;
+ setDirtyFlag(true);
+}
+
+F32 LLSettingsSky::getCloudShadow() const
+{
+ return mSettings[SETTING_CLOUD_SHADOW].asReal();
+}
+
+void LLSettingsSky::setCloudShadow(F32 val)
+{
+ setValue(SETTING_CLOUD_SHADOW, val);
+}
+
+F32 LLSettingsSky::getDomeOffset() const
+{
+ //return mSettings[SETTING_DOME_OFFSET].asReal();
+ return DOME_OFFSET;
+}
+
+F32 LLSettingsSky::getDomeRadius() const
+{
+ //return mSettings[SETTING_DOME_RADIUS].asReal();
+ return DOME_RADIUS;
+}
+
+F32 LLSettingsSky::getGamma() const
+{
+ return mSettings[SETTING_GAMMA].asReal();
+}
+
+void LLSettingsSky::setGamma(F32 val)
+{
+ mSettings[SETTING_GAMMA] = LLSD::Real(val);
+ setDirtyFlag(true);
+}
+
+LLColor3 LLSettingsSky::getGlow() const
+{
+ return LLColor3(mSettings[SETTING_GLOW]);
+}
+
+void LLSettingsSky::setGlow(const LLColor3 &val)
+{
+ setValue(SETTING_GLOW, val);
+}
+
+F32 LLSettingsSky::getMaxY() const
+{
+ return mSettings[SETTING_MAX_Y].asReal();
+}
+
+void LLSettingsSky::setMaxY(F32 val)
+{
+ setValue(SETTING_MAX_Y, val);
+}
+
+LLQuaternion LLSettingsSky::getMoonRotation() const
+{
+ return LLQuaternion(mSettings[SETTING_MOON_ROTATION]);
+}
+
+void LLSettingsSky::setMoonRotation(const LLQuaternion &val)
+{
+ setValue(SETTING_MOON_ROTATION, val);
+}
+
+F32 LLSettingsSky::getMoonScale() const
+{
+ return mSettings[SETTING_MOON_SCALE].asReal();
+}
+
+void LLSettingsSky::setMoonScale(F32 val)
+{
+ setValue(SETTING_MOON_SCALE, val);
+}
+
+LLUUID LLSettingsSky::getMoonTextureId() const
+{
+ return mSettings[SETTING_MOON_TEXTUREID].asUUID();
+}
+
+void LLSettingsSky::setMoonTextureId(LLUUID id)
+{
+ setValue(SETTING_MOON_TEXTUREID, id);
+}
+
+F32 LLSettingsSky::getStarBrightness() const
+{
+ return mSettings[SETTING_STAR_BRIGHTNESS].asReal();
+}
+
+void LLSettingsSky::setStarBrightness(F32 val)
+{
+ setValue(SETTING_STAR_BRIGHTNESS, val);
+}
+
+LLColor3 LLSettingsSky::getSunlightColor() const
+{
+ return LLColor3(mSettings[SETTING_SUNLIGHT_COLOR]);
+}
+
+void LLSettingsSky::setSunlightColor(const LLColor3 &val)
+{
+ setValue(SETTING_SUNLIGHT_COLOR, val);
+}
+
+LLQuaternion LLSettingsSky::getSunRotation() const
+{
+ return LLQuaternion(mSettings[SETTING_SUN_ROTATION]);
+}
+
+void LLSettingsSky::setSunRotation(const LLQuaternion &val)
+{
+ setValue(SETTING_SUN_ROTATION, val);
+}
+
+
+F32 LLSettingsSky::getSunScale() const
+{
+ return mSettings[SETTING_SUN_SCALE].asReal();
+}
+
+void LLSettingsSky::setSunScale(F32 val)
+{
+ setValue(SETTING_SUN_SCALE, val);
+}
+
+LLUUID LLSettingsSky::getSunTextureId() const
+{
+ return mSettings[SETTING_SUN_TEXTUREID].asUUID();
+}
+
+void LLSettingsSky::setSunTextureId(LLUUID id)
+{
+ setValue(SETTING_SUN_TEXTUREID, id);
+}
+
+LLUUID LLSettingsSky::getNextSunTextureId() const
+{
+ return mNextSunTextureId;
+}
+
+LLUUID LLSettingsSky::getNextMoonTextureId() const
+{
+ return mNextMoonTextureId;
+}
+
+LLUUID LLSettingsSky::getNextCloudNoiseTextureId() const
+{
+ return mNextCloudTextureId;
+}
+
+LLUUID LLSettingsSky::getNextBloomTextureId() const
+{
+ return mNextBloomTextureId;
+}
+
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
new file mode 100644
index 0000000000..a4ea8c98f4
--- /dev/null
+++ b/indra/llinventory/llsettingssky.h
@@ -0,0 +1,321 @@
+/**
+* @file llsettingssky.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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_SKY_H
+#define LL_SETTINGS_SKY_H
+
+#include "llsettingsbase.h"
+#include "v4coloru.h"
+
+const F32 EARTH_RADIUS = 6.370e6f;
+const F32 SUN_RADIUS = 695.508e6f;
+const F32 SUN_DIST = 149598.260e6f;
+const F32 MOON_RADIUS = 1.737e6f;
+const F32 MOON_DIST = 384.400e6f;
+
+class LLSettingsSky: public LLSettingsBase
+{
+public:
+ static const std::string SETTING_AMBIENT;
+ static const std::string SETTING_BLOOM_TEXTUREID;
+ static const std::string SETTING_BLUE_DENSITY;
+ static const std::string SETTING_BLUE_HORIZON;
+ static const std::string SETTING_DENSITY_MULTIPLIER;
+ static const std::string SETTING_DISTANCE_MULTIPLIER;
+ static const std::string SETTING_HAZE_DENSITY;
+ static const std::string SETTING_HAZE_HORIZON;
+ static const std::string SETTING_CLOUD_COLOR;
+ static const std::string SETTING_CLOUD_POS_DENSITY1;
+ static const std::string SETTING_CLOUD_POS_DENSITY2;
+ static const std::string SETTING_CLOUD_SCALE;
+ static const std::string SETTING_CLOUD_SCROLL_RATE;
+ static const std::string SETTING_CLOUD_SHADOW;
+ static const std::string SETTING_CLOUD_TEXTUREID;
+ static const std::string SETTING_DOME_OFFSET;
+ static const std::string SETTING_DOME_RADIUS;
+ static const std::string SETTING_GAMMA;
+ static const std::string SETTING_GLOW;
+ static const std::string SETTING_LIGHT_NORMAL;
+ static const std::string SETTING_MAX_Y;
+ static const std::string SETTING_MOON_ROTATION;
+ static const std::string SETTING_MOON_SCALE;
+ static const std::string SETTING_MOON_TEXTUREID;
+ static const std::string SETTING_STAR_BRIGHTNESS;
+ static const std::string SETTING_SUNLIGHT_COLOR;
+ static const std::string SETTING_SUN_ROTATION;
+ static const std::string SETTING_SUN_SCALE;
+ static const std::string SETTING_SUN_TEXTUREID;
+
+ static const std::string SETTING_PLANET_RADIUS;
+ static const std::string SETTING_SKY_BOTTOM_RADIUS;
+ static const std::string SETTING_SKY_TOP_RADIUS;
+ static const std::string SETTING_SUN_ARC_RADIANS;
+ static const std::string SETTING_MIE_ANISOTROPY_FACTOR;
+
+ static const std::string SETTING_RAYLEIGH_CONFIG;
+ static const std::string SETTING_MIE_CONFIG;
+ static const std::string SETTING_ABSORPTION_CONFIG;
+
+ static const std::string KEY_DENSITY_PROFILE;
+ static const std::string SETTING_DENSITY_PROFILE_WIDTH;
+ static const std::string SETTING_DENSITY_PROFILE_EXP_TERM;
+ static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR;
+ static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM;
+ static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM;
+
+
+ static const std::string SETTING_LEGACY_HAZE;
+
+ static const LLUUID DEFAULT_ASSET_ID;
+
+ typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t;
+
+ //---------------------------------------------------------------------
+ LLSettingsSky(const LLSD &data);
+ virtual ~LLSettingsSky() { };
+
+ virtual ptr_t buildClone() const = 0;
+
+ //---------------------------------------------------------------------
+ virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); }
+ virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; }
+
+ // Settings status
+ virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
+
+ virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
+
+ static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
+
+ F32 getPlanetRadius() const;
+ F32 getSkyBottomRadius() const;
+ F32 getSkyTopRadius() const;
+ F32 getSunArcRadians() const;
+ F32 getMieAnisotropy() const;
+
+ // Return first (only) profile layer represented in LLSD
+ LLSD getRayleighConfig() const;
+ LLSD getMieConfig() const;
+ LLSD getAbsorptionConfig() const;
+
+ // Return entire LLSDArray of profile layers represented in LLSD
+ LLSD getRayleighConfigs() const;
+ LLSD getMieConfigs() const;
+ LLSD getAbsorptionConfigs() const;
+
+ LLUUID getBloomTextureId() const;
+
+ void setRayleighConfigs(const LLSD& rayleighConfig);
+ void setMieConfigs(const LLSD& mieConfig);
+ void setAbsorptionConfigs(const LLSD& absorptionConfig);
+
+ //---------------------------------------------------------------------
+ LLColor3 getAmbientColor() const;
+ void setAmbientColor(const LLColor3 &val);
+
+ LLColor3 getCloudColor() const;
+ void setCloudColor(const LLColor3 &val);
+
+ LLUUID getCloudNoiseTextureId() const;
+ void setCloudNoiseTextureId(const LLUUID &id);
+
+ LLColor3 getCloudPosDensity1() const;
+ void setCloudPosDensity1(const LLColor3 &val);
+
+ LLColor3 getCloudPosDensity2() const;
+ void setCloudPosDensity2(const LLColor3 &val);
+
+ F32 getCloudScale() const;
+ void setCloudScale(F32 val);
+
+ LLVector2 getCloudScrollRate() const;
+ void setCloudScrollRate(const LLVector2 &val);
+
+ void setCloudScrollRateX(F32 val);
+ void setCloudScrollRateY(F32 val);
+
+ F32 getCloudShadow() const;
+ void setCloudShadow(F32 val);
+
+ F32 getDomeOffset() const;
+ F32 getDomeRadius() const;
+
+ F32 getGamma() const;
+
+ void setGamma(F32 val);
+
+ LLColor3 getGlow() const;
+ void setGlow(const LLColor3 &val);
+
+ F32 getMaxY() const;
+
+ void setMaxY(F32 val);
+
+ LLQuaternion getMoonRotation() const;
+ void setMoonRotation(const LLQuaternion &val);
+
+ F32 getMoonScale() const;
+ void setMoonScale(F32 val);
+
+ LLUUID getMoonTextureId() const;
+ void setMoonTextureId(LLUUID id);
+
+ F32 getStarBrightness() const;
+ void setStarBrightness(F32 val);
+
+ LLColor3 getSunlightColor() const;
+ void setSunlightColor(const LLColor3 &val);
+
+ LLQuaternion getSunRotation() const;
+ void setSunRotation(const LLQuaternion &val) ;
+
+ F32 getSunScale() const;
+ void setSunScale(F32 val);
+
+ LLUUID getSunTextureId() const;
+ void setSunTextureId(LLUUID id);
+
+ //=====================================================================
+ // transient properties used in animations.
+ LLUUID getNextSunTextureId() const;
+ LLUUID getNextMoonTextureId() const;
+ LLUUID getNextCloudNoiseTextureId() const;
+ LLUUID getNextBloomTextureId() const;
+
+ //=====================================================================
+ virtual void loadTextures() { };
+
+ //=====================================================================
+ virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
+ static validation_list_t validationList();
+
+ static LLSD translateLegacySettings(const LLSD& legacy);
+
+// LEGACY_ATMOSPHERICS
+ static LLSD translateLegacyHazeSettings(const LLSD& legacy);
+
+ LLColor3 getLightAttenuation(F32 distance) const;
+ LLColor3 getLightTransmittance() const;
+ LLColor3 gammaCorrect(const LLColor3& in) const;
+
+ LLColor3 getBlueDensity() const;
+ LLColor3 getBlueHorizon() const;
+ F32 getHazeDensity() const;
+ F32 getHazeHorizon() const;
+ F32 getDensityMultiplier() const;
+ F32 getDistanceMultiplier() const;
+
+ void setBlueDensity(const LLColor3 &val);
+ void setBlueHorizon(const LLColor3 &val);
+ void setDensityMultiplier(F32 val);
+ void setDistanceMultiplier(F32 val);
+ void setHazeDensity(F32 val);
+ void setHazeHorizon(F32 val);
+
+// Internal/calculated settings
+ bool getIsSunUp() const;
+ bool getIsMoonUp() const;
+
+ LLVector3 getLightDirection() const;
+ LLVector3 getSunDirection() const;
+ LLVector3 getMoonDirection() const;
+ LLColor4U getFadeColor() const;
+ LLColor4 getMoonAmbient() const;
+ LLColor3 getMoonDiffuse() const;
+ LLColor4 getSunAmbient() const;
+ LLColor3 getSunDiffuse() const;
+ LLColor4 getTotalAmbient() const;
+
+ virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
+
+ static LLUUID GetDefaultAssetId();
+ static LLUUID GetDefaultSunTextureId();
+ static LLUUID GetBlankSunTextureId();
+ static LLUUID GetDefaultMoonTextureId();
+ static LLUUID GetDefaultCloudNoiseTextureId();
+ static LLUUID GetDefaultBloomTextureId();
+
+ static LLSD createDensityProfileLayer(
+ F32 width,
+ F32 exponential_term,
+ F32 exponential_scale_factor,
+ F32 linear_term,
+ F32 constant_term,
+ F32 aniso_factor = 0.0f);
+
+ static LLSD createSingleLayerDensityProfile(
+ F32 width,
+ F32 exponential_term,
+ F32 exponential_scale_factor,
+ F32 linear_term,
+ F32 constant_term,
+ F32 aniso_factor = 0.0f);
+
+protected:
+ static const std::string SETTING_LEGACY_EAST_ANGLE;
+ static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL;
+ static const std::string SETTING_LEGACY_SUN_ANGLE;
+
+ LLSettingsSky();
+
+ virtual stringset_t getSlerpKeys() const SETTINGS_OVERRIDE;
+ virtual stringset_t getSkipInterpolateKeys() const SETTINGS_OVERRIDE;
+ virtual void updateSettings() SETTINGS_OVERRIDE;
+
+private:
+ static LLSD rayleighConfigDefault();
+ static LLSD absorptionConfigDefault();
+ static LLSD mieConfigDefault();
+
+ void calculateHeavenlyBodyPositions() const;
+ void calculateLightSettings() const;
+
+ mutable LLVector3 mSunDirection;
+ mutable LLVector3 mMoonDirection;
+ mutable LLVector3 mLightDirection;
+
+ static const F32 DOME_RADIUS;
+ static const F32 DOME_OFFSET;
+
+ mutable LLColor4U mFadeColor;
+ mutable LLColor4 mMoonAmbient;
+ mutable LLColor3 mMoonDiffuse;
+ mutable LLColor4 mSunAmbient;
+ mutable LLColor3 mSunDiffuse;
+ mutable LLColor4 mTotalAmbient;
+
+ LLUUID mNextSunTextureId;
+ LLUUID mNextMoonTextureId;
+ LLUUID mNextCloudTextureId;
+ LLUUID mNextBloomTextureId;
+
+ typedef std::map<std::string, S32> mapNameToUniformId_t;
+
+ static mapNameToUniformId_t sNameToUniformMapping;
+};
+
+#endif
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
new file mode 100644
index 0000000000..33f824028b
--- /dev/null
+++ b/indra/llinventory/llsettingswater.cpp
@@ -0,0 +1,269 @@
+/**
+* @file llsettingswater.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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 "llsettingswater.h"
+#include <algorithm>
+#include <boost/make_shared.hpp>
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "v3colorutil.h"
+#include "indra_constants.h"
+
+//=========================================================================
+namespace
+{
+ LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
+ LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
+}
+
+//=========================================================================
+const std::string LLSettingsWater::SETTING_BLUR_MULTIPILER("blur_multiplier");
+const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color");
+const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density");
+const std::string LLSettingsWater::SETTING_FOG_MOD("underwater_fog_mod");
+const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET("fresnel_offset");
+const std::string LLSettingsWater::SETTING_FRESNEL_SCALE("fresnel_scale");
+const std::string LLSettingsWater::SETTING_TRANSPARENT_TEXTURE("transparent_texture");
+const std::string LLSettingsWater::SETTING_NORMAL_MAP("normal_map");
+const std::string LLSettingsWater::SETTING_NORMAL_SCALE("normal_scale");
+const std::string LLSettingsWater::SETTING_SCALE_ABOVE("scale_above");
+const std::string LLSettingsWater::SETTING_SCALE_BELOW("scale_below");
+const std::string LLSettingsWater::SETTING_WAVE1_DIR("wave1_direction");
+const std::string LLSettingsWater::SETTING_WAVE2_DIR("wave2_direction");
+
+const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPILER("blurMultiplier");
+const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR("waterFogColor");
+const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY("waterFogDensity");
+const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD("underWaterFogMod");
+const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET("fresnelOffset");
+const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE("fresnelScale");
+const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP("normalMap");
+const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE("normScale");
+const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE("scaleAbove");
+const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW("scaleBelow");
+const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR("wave1Dir");
+const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR("wave2Dir");
+
+const LLUUID LLSettingsWater::DEFAULT_ASSET_ID("ce4cfe94-700a-292c-7c22-a2d9201bd661");
+
+static const LLUUID DEFAULT_TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
+static const LLUUID DEFAULT_OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
+
+//=========================================================================
+LLSettingsWater::LLSettingsWater(const LLSD &data) :
+ LLSettingsBase(data),
+ mNextNormalMapID()
+{
+}
+
+LLSettingsWater::LLSettingsWater() :
+ LLSettingsBase(),
+ mNextNormalMapID()
+{
+}
+
+//=========================================================================
+LLSD LLSettingsWater::defaults(const LLSettingsBase::TrackPosition& position)
+{
+ static LLSD dfltsetting;
+
+ if (dfltsetting.size() == 0)
+ {
+ // give the normal scale offset some variability over track time...
+ F32 normal_scale_offset = (position * 0.5f) - 0.25f;
+
+ // Magic constants copied form defaults.xml
+ dfltsetting[SETTING_BLUR_MULTIPILER] = LLSD::Real(0.04000f);
+ dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue();
+ dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f);
+ dfltsetting[SETTING_FOG_MOD] = LLSD::Real(0.25f);
+ dfltsetting[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5f);
+ dfltsetting[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999);
+ dfltsetting[SETTING_TRANSPARENT_TEXTURE] = GetDefaultTransparentTextureAssetId();
+ dfltsetting[SETTING_NORMAL_MAP] = GetDefaultWaterNormalAssetId();
+ dfltsetting[SETTING_NORMAL_SCALE] = LLVector3(2.0f + normal_scale_offset, 2.0f + normal_scale_offset, 2.0f + normal_scale_offset).getValue();
+ dfltsetting[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299f);
+ dfltsetting[SETTING_SCALE_BELOW] = LLSD::Real(0.2000f);
+ dfltsetting[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42000f).getValue();
+ dfltsetting[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16000f).getValue();
+
+ dfltsetting[SETTING_TYPE] = "water";
+ }
+
+ return dfltsetting;
+}
+
+LLSD LLSettingsWater::translateLegacySettings(LLSD legacy)
+{
+ LLSD newsettings(defaults());
+
+ if (legacy.has(SETTING_LEGACY_BLUR_MULTIPILER))
+ {
+ newsettings[SETTING_BLUR_MULTIPILER] = LLSD::Real(legacy[SETTING_LEGACY_BLUR_MULTIPILER].asReal());
+ }
+ if (legacy.has(SETTING_LEGACY_FOG_COLOR))
+ {
+ newsettings[SETTING_FOG_COLOR] = LLColor3(legacy[SETTING_LEGACY_FOG_COLOR]).getValue();
+ }
+ if (legacy.has(SETTING_LEGACY_FOG_DENSITY))
+ {
+ newsettings[SETTING_FOG_DENSITY] = LLSD::Real(legacy[SETTING_LEGACY_FOG_DENSITY]);
+ }
+ if (legacy.has(SETTING_LEGACY_FOG_MOD))
+ {
+ newsettings[SETTING_FOG_MOD] = LLSD::Real(legacy[SETTING_LEGACY_FOG_MOD].asReal());
+ }
+ if (legacy.has(SETTING_LEGACY_FRESNEL_OFFSET))
+ {
+ newsettings[SETTING_FRESNEL_OFFSET] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_OFFSET].asReal());
+ }
+ if (legacy.has(SETTING_LEGACY_FRESNEL_SCALE))
+ {
+ newsettings[SETTING_FRESNEL_SCALE] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_SCALE].asReal());
+ }
+ if (legacy.has(SETTING_LEGACY_NORMAL_MAP))
+ {
+ newsettings[SETTING_NORMAL_MAP] = LLSD::UUID(legacy[SETTING_LEGACY_NORMAL_MAP].asUUID());
+ }
+ if (legacy.has(SETTING_LEGACY_NORMAL_SCALE))
+ {
+ newsettings[SETTING_NORMAL_SCALE] = LLVector3(legacy[SETTING_LEGACY_NORMAL_SCALE]).getValue();
+ }
+ if (legacy.has(SETTING_LEGACY_SCALE_ABOVE))
+ {
+ newsettings[SETTING_SCALE_ABOVE] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_ABOVE].asReal());
+ }
+ if (legacy.has(SETTING_LEGACY_SCALE_BELOW))
+ {
+ newsettings[SETTING_SCALE_BELOW] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_BELOW].asReal());
+ }
+ if (legacy.has(SETTING_LEGACY_WAVE1_DIR))
+ {
+ newsettings[SETTING_WAVE1_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE1_DIR]).getValue();
+ }
+ if (legacy.has(SETTING_LEGACY_WAVE2_DIR))
+ {
+ newsettings[SETTING_WAVE2_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE2_DIR]).getValue();
+ }
+
+ return newsettings;
+}
+
+void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
+{
+ LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast<LLSettingsWater>(end);
+ if (other)
+ {
+ LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf);
+ replaceSettings(blenddata);
+ mNextNormalMapID = other->getNormalMapID();
+ mNextTransparentTextureID = other->getTransparentTextureID();
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "Could not cast end settings to water. No blend performed." << LL_ENDL;
+ }
+ setBlendFactor(blendf);
+}
+
+void LLSettingsWater::replaceSettings(LLSD settings)
+{
+ LLSettingsBase::replaceSettings(settings);
+ mNextNormalMapID.setNull();
+ mNextTransparentTextureID.setNull();
+}
+
+LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const
+{
+ return LLSettingsWater::validationList();
+}
+
+LLSettingsWater::validation_list_t LLSettingsWater::validationList()
+{
+ static validation_list_t validation;
+
+ if (validation.empty())
+ { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
+ // copy constructor for LLSDArray. Directly binding the LLSDArray as
+ // a parameter without first wrapping it in a pure LLSD object will result
+ // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
+
+ validation.push_back(Validator(SETTING_BLUR_MULTIPILER, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-0.5f)(0.5f)))));
+ validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
+ LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f)))));
+ validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f)))));
+ validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
+ LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
+ validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
+ validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
+ validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(-20.0f)(-20.0f)),
+ LLSD(LLSDArray(20.0f)(20.0f)))));
+ validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(-20.0f)(-20.0f)),
+ LLSD(LLSDArray(20.0f)(20.0f)))));
+ }
+
+ return validation;
+}
+
+LLUUID LLSettingsWater::GetDefaultAssetId()
+{
+ return DEFAULT_ASSET_ID;
+}
+
+LLUUID LLSettingsWater::GetDefaultWaterNormalAssetId()
+{
+ return DEFAULT_WATER_NORMAL;
+}
+
+LLUUID LLSettingsWater::GetDefaultTransparentTextureAssetId()
+{
+ return DEFAULT_TRANSPARENT_WATER_TEXTURE;
+}
+
+LLUUID LLSettingsWater::GetDefaultOpaqueTextureAssetId()
+{
+ return DEFAULT_OPAQUE_WATER_TEXTURE;
+}
diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h
new file mode 100644
index 0000000000..06ee8e68bc
--- /dev/null
+++ b/indra/llinventory/llsettingswater.h
@@ -0,0 +1,246 @@
+/**
+* @file llsettingssky.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $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_WATER_H
+#define LL_SETTINGS_WATER_H
+
+#include "llsettingsbase.h"
+
+class LLSettingsWater : public LLSettingsBase
+{
+public:
+ static const std::string SETTING_BLUR_MULTIPILER;
+ static const std::string SETTING_FOG_COLOR;
+ static const std::string SETTING_FOG_DENSITY;
+ static const std::string SETTING_FOG_MOD;
+ static const std::string SETTING_FRESNEL_OFFSET;
+ static const std::string SETTING_FRESNEL_SCALE;
+ static const std::string SETTING_TRANSPARENT_TEXTURE;
+ static const std::string SETTING_NORMAL_MAP;
+ static const std::string SETTING_NORMAL_SCALE;
+ static const std::string SETTING_SCALE_ABOVE;
+ static const std::string SETTING_SCALE_BELOW;
+ static const std::string SETTING_WAVE1_DIR;
+ static const std::string SETTING_WAVE2_DIR;
+
+ static const LLUUID DEFAULT_ASSET_ID;
+
+ typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> ptr_t;
+
+ //---------------------------------------------------------------------
+ LLSettingsWater(const LLSD &data);
+ virtual ~LLSettingsWater() { };
+
+ virtual ptr_t buildClone() const = 0;
+
+ //---------------------------------------------------------------------
+ virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("water"); }
+ virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_WATER; }
+
+ // Settings status
+ virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
+
+ virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
+
+ static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
+
+ //---------------------------------------------------------------------
+ F32 getBlurMultiplier() const
+ {
+ return mSettings[SETTING_BLUR_MULTIPILER].asReal();
+ }
+
+ void setBlurMultiplier(F32 val)
+ {
+ setValue(SETTING_BLUR_MULTIPILER, val);
+ }
+
+ LLColor3 getWaterFogColor() const
+ {
+ return LLColor3(mSettings[SETTING_FOG_COLOR]);
+ }
+
+ void setWaterFogColor(LLColor3 val)
+ {
+ setValue(SETTING_FOG_COLOR, val);
+ }
+
+ F32 getWaterFogDensity() const
+ {
+ return mSettings[SETTING_FOG_DENSITY].asReal();
+ }
+
+ void setWaterFogDensity(F32 val)
+ {
+ setValue(SETTING_FOG_DENSITY, val);
+ }
+
+ F32 getFogMod() const
+ {
+ return mSettings[SETTING_FOG_MOD].asReal();
+ }
+
+ void setFogMod(F32 val)
+ {
+ setValue(SETTING_FOG_MOD, val);
+ }
+
+ F32 getFresnelOffset() const
+ {
+ return mSettings[SETTING_FRESNEL_OFFSET].asReal();
+ }
+
+ void setFresnelOffset(F32 val)
+ {
+ setValue(SETTING_FRESNEL_OFFSET, val);
+ }
+
+ F32 getFresnelScale() const
+ {
+ return mSettings[SETTING_FRESNEL_SCALE].asReal();
+ }
+
+ void setFresnelScale(F32 val)
+ {
+ setValue(SETTING_FRESNEL_SCALE, val);
+ }
+
+ LLUUID getTransparentTextureID() const
+ {
+ return mSettings[SETTING_TRANSPARENT_TEXTURE].asUUID();
+ }
+
+ void setTransparentTextureID(LLUUID val)
+ {
+ setValue(SETTING_TRANSPARENT_TEXTURE, val);
+ }
+
+ LLUUID getNormalMapID() const
+ {
+ return mSettings[SETTING_NORMAL_MAP].asUUID();
+ }
+
+ void setNormalMapID(LLUUID val)
+ {
+ setValue(SETTING_NORMAL_MAP, val);
+ }
+
+ LLVector3 getNormalScale() const
+ {
+ return LLVector3(mSettings[SETTING_NORMAL_SCALE]);
+ }
+
+ void setNormalScale(LLVector3 val)
+ {
+ setValue(SETTING_NORMAL_SCALE, val);
+ }
+
+ F32 getScaleAbove() const
+ {
+ return mSettings[SETTING_SCALE_ABOVE].asReal();
+ }
+
+ void setScaleAbove(F32 val)
+ {
+ setValue(SETTING_SCALE_ABOVE, val);
+ }
+
+ F32 getScaleBelow() const
+ {
+ return mSettings[SETTING_SCALE_BELOW].asReal();
+ }
+
+ void setScaleBelow(F32 val)
+ {
+ setValue(SETTING_SCALE_BELOW, val);
+ }
+
+ LLVector2 getWave1Dir() const
+ {
+ return LLVector2(mSettings[SETTING_WAVE1_DIR]);
+ }
+
+ void setWave1Dir(LLVector2 val)
+ {
+ setValue(SETTING_WAVE1_DIR, val);
+ }
+
+ LLVector2 getWave2Dir() const
+ {
+ return LLVector2(mSettings[SETTING_WAVE2_DIR]);
+ }
+
+ void setWave2Dir(LLVector2 val)
+ {
+ setValue(SETTING_WAVE2_DIR, val);
+ }
+
+ //-------------------------------------------
+ LLUUID getNextNormalMapID() const
+ {
+ return mNextNormalMapID;
+ }
+
+ LLUUID getNextTransparentTextureID() const
+ {
+ return mNextTransparentTextureID;
+ }
+
+ virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
+ static validation_list_t validationList();
+
+ static LLSD translateLegacySettings(LLSD legacy);
+
+ virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
+
+ static LLUUID GetDefaultAssetId();
+ static LLUUID GetDefaultWaterNormalAssetId();
+ static LLUUID GetDefaultTransparentTextureAssetId();
+ static LLUUID GetDefaultOpaqueTextureAssetId();
+
+protected:
+ static const std::string SETTING_LEGACY_BLUR_MULTIPILER;
+ static const std::string SETTING_LEGACY_FOG_COLOR;
+ static const std::string SETTING_LEGACY_FOG_DENSITY;
+ static const std::string SETTING_LEGACY_FOG_MOD;
+ static const std::string SETTING_LEGACY_FRESNEL_OFFSET;
+ static const std::string SETTING_LEGACY_FRESNEL_SCALE;
+ static const std::string SETTING_LEGACY_NORMAL_MAP;
+ static const std::string SETTING_LEGACY_NORMAL_SCALE;
+ static const std::string SETTING_LEGACY_SCALE_ABOVE;
+ static const std::string SETTING_LEGACY_SCALE_BELOW;
+ static const std::string SETTING_LEGACY_WAVE1_DIR;
+ static const std::string SETTING_LEGACY_WAVE2_DIR;
+
+ LLSettingsWater();
+
+private:
+ LLUUID mNextTransparentTextureID;
+ LLUUID mNextNormalMapID;
+};
+
+#endif
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 4c8bcdac91..61d13c0b1c 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -87,6 +87,7 @@ set(llmath_HEADER_FILES
raytrace.h
v2math.h
v3color.h
+ v3colorutil.h
v3dmath.h
v3math.h
v4color.h
diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp
index 47374c287f..a8d9eba2a0 100644
--- a/indra/llmath/llquaternion.cpp
+++ b/indra/llmath/llquaternion.cpp
@@ -103,6 +103,10 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
*this = mat.quaternion();
normalize();
}
+LLQuaternion::LLQuaternion(const LLSD &sd)
+{
+ setValue(sd);
+}
// Quatizations
void LLQuaternion::quantize16(F32 lower, F32 upper)
@@ -860,6 +864,26 @@ void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
}
}
+const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians)
+{
+ // euler angle inputs are complements of azimuth/altitude which are measured from zenith
+ F32 pitch = llclamp(F_PI_BY_TWO - altitudeRadians, 0.0f, F_PI_BY_TWO);
+ F32 yaw = llclamp(F_PI_BY_TWO - azimuthRadians, 0.0f, F_PI_BY_TWO);
+ setEulerAngles(0.0f, pitch, yaw);
+ return *this;
+}
+
+void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadians)
+{
+ F32 rick_roll;
+ F32 pitch;
+ F32 yaw;
+ getEulerAngles(&rick_roll, &pitch, &yaw);
+ // make these measured from zenith
+ altitudeRadians = llclamp(F_PI_BY_TWO - pitch, 0.0f, F_PI_BY_TWO);
+ azimuthRadians = llclamp(F_PI_BY_TWO - yaw, 0.0f, F_PI_BY_TWO);
+}
+
// quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{
diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h
index aa0b1752f4..e2cdad548b 100644
--- a/indra/llmath/llquaternion.h
+++ b/indra/llmath/llquaternion.h
@@ -28,6 +28,7 @@
#define LLQUATERNION_H
#include <iostream>
+#include "llsd.h"
#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
#error "Please include llmath.h first."
@@ -63,6 +64,10 @@ public:
LLQuaternion(const LLVector3 &x_axis,
const LLVector3 &y_axis,
const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
+ explicit LLQuaternion(const LLSD &sd); // Initializes Quaternion from LLSD array.
+
+ LLSD getValue() const;
+ void setValue(const LLSD& sd);
BOOL isIdentity() const;
BOOL isNotIdentity() const;
@@ -79,7 +84,8 @@ public:
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat)
-
+ const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude);
+
const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector4 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
@@ -100,6 +106,7 @@ public:
void getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z
void getAngleAxis(F32* angle, LLVector3 &vec) const;
void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;
+ void getAzimuthAndAltitude(F32 &azimuth, F32 &altitude);
F32 normalize(); // Normalizes Quaternion and returns magnitude
F32 normQuat(); // deprecated
@@ -166,6 +173,25 @@ public:
//static U32 mMultCount;
};
+inline LLSD LLQuaternion::getValue() const
+{
+ LLSD ret;
+ ret[0] = mQ[0];
+ ret[1] = mQ[1];
+ ret[2] = mQ[2];
+ ret[3] = mQ[3];
+ return ret;
+}
+
+inline void LLQuaternion::setValue(const LLSD& sd)
+{
+ mQ[0] = sd[0].asReal();
+ mQ[1] = sd[1].asReal();
+ mQ[2] = sd[2].asReal();
+ mQ[3] = sd[3].asReal();
+}
+
+
// checker
inline BOOL LLQuaternion::isFinite() const
{
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 6b6cd65ce2..b1d1b9a3e8 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2192,6 +2192,12 @@ BOOL LLVolume::generate()
LLVector4a* end_profile = profile+sizeT;
LLVector4a offset = mPathp->mPath[s].mPos;
+ if (!offset.isFinite3())
+ { // MAINT-5660; don't know why this happens, does not affect Release builds
+ LL_WARNS() << "LLVolume using path with non-finite points. Resetting them to 0,0,0" << LL_ENDL;
+ offset.clear();
+ }
+
LLVector4a tmp;
// Run along the profile.
@@ -2199,7 +2205,7 @@ BOOL LLVolume::generate()
{
rot_mat.rotate(*profile++, tmp);
dst->setAdd(tmp,offset);
- llassert(dst->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds
+
++dst;
}
}
diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp
index 802ddb9e57..65eb3348de 100644
--- a/indra/llmath/m3math.cpp
+++ b/indra/llmath/m3math.cpp
@@ -75,13 +75,6 @@ LLMatrix3::LLMatrix3(const F32 angle, const LLVector4 &vec)
setRot(quat);
}
-LLMatrix3::LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLVector3 vec(x, y, z);
- LLQuaternion quat(angle, vec);
- setRot(quat);
-}
-
LLMatrix3::LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw)
{
setRot(roll,pitch,yaw);
@@ -294,14 +287,6 @@ LLQuaternion LLMatrix3::quaternion() const
return quat;
}
-
-// These functions take Rotation arguments
-const LLMatrix3& LLMatrix3::setRot(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- setRot(LLQuaternion(angle,x,y,z));
- return *this;
-}
-
const LLMatrix3& LLMatrix3::setRot(const F32 angle, const LLVector3 &vec)
{
setRot(LLQuaternion(angle, vec));
@@ -394,15 +379,6 @@ const LLMatrix3& LLMatrix3::setCol( U32 colIndex, const LLVector3& col )
return *this;
}
-
-// Rotate exisitng mMatrix
-const LLMatrix3& LLMatrix3::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLMatrix3 mat(angle, x, y, z);
- *this *= mat;
- return *this;
-}
-
const LLMatrix3& LLMatrix3::rotate(const F32 angle, const LLVector3 &vec)
{
diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h
index 2be5452f8d..bf38895855 100644
--- a/indra/llmath/m3math.h
+++ b/indra/llmath/m3math.h
@@ -60,7 +60,6 @@ class LLMatrix3
explicit LLMatrix3(const F32 *mat); // Initializes Matrix to values in mat
explicit LLMatrix3(const LLQuaternion &q); // Initializes Matrix with rotation q
- LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector3 &vec); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector3d &vec); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector4 &vec); // Initializes Matrix with axis angle
@@ -81,8 +80,7 @@ class LLMatrix3
// Matrix setters - set some properties without modifying others
//
- // These functions take Rotation arguments
- const LLMatrix3& setRot(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix for rotating angle radians about (x, y, z)
+ // These functions take Rotation arguments
const LLMatrix3& setRot(const F32 angle, const LLVector3 &vec); // Calculate rotation matrix for rotating angle radians about vec
const LLMatrix3& setRot(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
const LLMatrix3& setRot(const LLQuaternion &q); // Transform matrix by Euler angles and translating by pos
diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp
index d89c482804..3baf1bad18 100644
--- a/indra/llmath/m4math.cpp
+++ b/indra/llmath/m4math.cpp
@@ -384,13 +384,6 @@ void LLMatrix4::initRows(const LLVector4 &row0,
}
-const LLMatrix4& LLMatrix4::initRotation(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLMatrix3 mat(angle, x, y, z);
- return initMatrix(mat);
-}
-
-
const LLMatrix4& LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)
{
LLMatrix3 mat(angle, vec);
@@ -412,17 +405,6 @@ const LLMatrix4& LLMatrix4::initRotation(const LLQuaternion &q)
}
-// Position and Rotation
-const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const F32 rx, const F32 ry, const F32 rz,
- const F32 tx, const F32 ty, const F32 tz)
-{
- LLMatrix3 mat(angle, rx, ry, rz);
- LLVector3 translation(tx, ty, tz);
- initMatrix(mat);
- setTranslation(translation);
- return (*this);
-}
-
const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)
{
LLMatrix3 mat(angle, axis);
@@ -513,15 +495,6 @@ const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &
return (*this);
}
-// Rotate exisitng mMatrix
-const LLMatrix4& LLMatrix4::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLVector4 vec4(x, y, z);
- LLMatrix4 mat(angle, vec4);
- *this *= mat;
- return *this;
-}
-
const LLMatrix4& LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)
{
LLMatrix4 mat(angle, vec);
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index a77c5bc76d..bf60adb9b6 100644
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
@@ -137,7 +137,6 @@ public:
bool isIdentity() const;
const LLMatrix4& setZero(); // Clears matrix to all zeros.
- const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix by rotating angle radians about (x, y, z)
const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis); // Calculate rotation matrix for rotating angle radians about vec
const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
const LLMatrix4& initRotation(const LLQuaternion &q); // Set with Quaternion and position
@@ -148,10 +147,6 @@ public:
// These operation create a matrix that will rotate and translate by the
// specified amounts.
- const LLMatrix4& initRotTrans(const F32 angle,
- const F32 rx, const F32 ry, const F32 rz,
- const F32 px, const F32 py, const F32 pz);
-
const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation); // Rotation from axis angle + translation
const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation
const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position
@@ -211,7 +206,6 @@ public:
// Rotate existing matrix
// These are really, really, inefficient as implemented! - djs
- const LLMatrix4& rotate(const F32 angle, const F32 x, const F32 y, const F32 z); // Rotate matrix by rotating angle radians about (x, y, z)
const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec); // Rotate matrix by rotating angle radians about vec
const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw); // Rotate matrix by Euler angles
const LLMatrix4& rotate(const LLQuaternion &q); // Rotate matrix by Quaternion
diff --git a/indra/llmath/tests/m3math_test.cpp b/indra/llmath/tests/m3math_test.cpp
index 1ca2b005d9..2a0fe76aa7 100644
--- a/indra/llmath/tests/m3math_test.cpp
+++ b/indra/llmath/tests/m3math_test.cpp
@@ -77,7 +77,7 @@ namespace tut
template<> template<>
void m3math_test_object_t::test<2>()
{
- LLMatrix3 llmat3_obj(30, 1, 2, 3);
+ LLMatrix3 llmat3_obj;
llmat3_obj.setZero();
ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] &&
diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp
index a0cd642853..a24571f2c8 100644
--- a/indra/llmath/v2math.cpp
+++ b/indra/llmath/v2math.cpp
@@ -118,7 +118,7 @@ LLSD LLVector2::getValue() const
return ret;
}
-void LLVector2::setValue(LLSD& sd)
+void LLVector2::setValue(const LLSD& sd)
{
mV[0] = (F32) sd[0].asReal();
mV[1] = (F32) sd[1].asReal();
diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h
index 8d5db96f5e..2335a2e327 100644
--- a/indra/llmath/v2math.h
+++ b/indra/llmath/v2math.h
@@ -49,6 +49,7 @@ class LLVector2
LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y)
LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1])
explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])
+ explicit LLVector2(const LLSD &sd);
// Clears LLVector2 to (0, 0). DEPRECATED - prefer zeroVec.
void clear();
@@ -61,7 +62,7 @@ class LLVector2
void set(const F32 *vec); // Sets LLVector2 to vec
LLSD getValue() const;
- void setValue(LLSD& sd);
+ void setValue(const LLSD& sd);
void setVec(F32 x, F32 y); // deprecated
void setVec(const LLVector2 &vec); // deprecated
@@ -145,6 +146,10 @@ inline LLVector2::LLVector2(const LLVector3 &vec)
mV[VY] = vec.mV[VY];
}
+inline LLVector2::LLVector2(const LLSD &sd)
+{
+ setValue(sd);
+}
// Clear and Assignment Functions
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index daf3a6857b..43910a1bbe 100644
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -100,6 +100,23 @@ public:
const LLColor3& operator=(const LLColor4 &a);
+ LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2)
+ {
+ return LLColor3(
+ mV[0] / col2.mV[0],
+ mV[1] / col2.mV[1],
+ mV[2] / col2.mV[2] );
+ }
+
+ LL_FORCE_INLINE LLColor3 color_norm()
+ {
+ F32 l = length();
+ return LLColor3(
+ mV[0] / l,
+ mV[1] / l,
+ mV[2] / l );
+ }
+
friend std::ostream& operator<<(std::ostream& s, const LLColor3 &a); // Print a
friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b); // Return vector a + b
friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b); // Return vector a minus b
diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h
new file mode 100644
index 0000000000..6d8cd9329b
--- /dev/null
+++ b/indra/llmath/v3colorutil.h
@@ -0,0 +1,115 @@
+/**
+ * @file v3color.h
+ * @brief LLColor3 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_V3COLORUTIL_H
+#define LL_V3COLORUTIL_H
+
+#include "v3color.h"
+
+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]);
+}
+
+
+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]);
+}
+
+
+inline LLColor3 componentExp(LLColor3 const &v)
+{
+ return LLColor3(exp(v.mV[0]),
+ exp(v.mV[1]),
+ exp(v.mV[2]));
+}
+
+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));
+}
+
+inline LLColor3 componentSaturate(LLColor3 const &v)
+{
+ 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));
+}
+
+
+inline LLColor3 componentSqrt(LLColor3 const &v)
+{
+ return LLColor3(sqrt(v.mV[0]),
+ sqrt(v.mV[1]),
+ sqrt(v.mV[2]));
+}
+
+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];
+}
+
+inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
+{
+ return (left + ((right - left) * amount));
+}
+
+inline LLColor3 smear(F32 val)
+{
+ return LLColor3(val, val, val);
+}
+
+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]);
+}
+
+#endif
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 8f353ead5a..614cdc9f3e 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -114,9 +114,11 @@ class LLColor4
friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b
friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b
friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change)
+ friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change)
friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change)
friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change)
friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change)
+
friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b
friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b
@@ -477,6 +479,15 @@ inline LLColor4 operator*(const LLColor4 &a, F32 k)
a.mV[VW]);
}
+inline LLColor4 operator/(const LLColor4 &a, F32 k)
+{
+ return LLColor4(
+ a.mV[VX] / k,
+ a.mV[VY] / k,
+ a.mV[VZ] / k,
+ a.mV[VW]);
+}
+
inline LLColor4 operator*(F32 k, const LLColor4 &a)
{
// only affects rgb (not a!)
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index 623c8b2003..3f6d480ed9 100644
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
@@ -30,6 +30,7 @@
#include "llerror.h"
#include "llmath.h"
#include "v3math.h"
+#include "v2math.h"
class LLMatrix3;
class LLMatrix4;
@@ -46,8 +47,11 @@ class LLVector4
LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
+ explicit LLVector4(const LLVector2 &vec);
+ explicit LLVector4(const LLVector2 &vec, F32 z, F32 w);
explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
+ explicit LLVector4(const LLSD &sd);
LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
LLVector4(F32 x, F32 y, F32 z, F32 w);
@@ -61,6 +65,15 @@ class LLVector4
return ret;
}
+ void setValue(const LLSD& sd)
+ {
+ mV[0] = sd[0].asReal();
+ mV[1] = sd[1].asReal();
+ mV[2] = sd[2].asReal();
+ mV[3] = sd[3].asReal();
+ }
+
+
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
@@ -175,6 +188,22 @@ inline LLVector4::LLVector4(const F64 *vec)
mV[VW] = (F32) vec[VW];
}
+inline LLVector4::LLVector4(const LLVector2 &vec)
+{
+ mV[VX] = vec[VX];
+ mV[VY] = vec[VY];
+ mV[VZ] = 0.f;
+ mV[VW] = 0.f;
+}
+
+inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)
+{
+ mV[VX] = vec[VX];
+ mV[VY] = vec[VY];
+ mV[VZ] = z;
+ mV[VW] = w;
+}
+
inline LLVector4::LLVector4(const LLVector3 &vec)
{
mV[VX] = vec.mV[VX];
@@ -191,6 +220,11 @@ inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
mV[VW] = w;
}
+inline LLVector4::LLVector4(const LLSD &sd)
+{
+ setValue(sd);
+}
+
inline BOOL LLVector4::isFinite() const
{
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 596d57c7b7..2b12a062c3 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -62,6 +62,42 @@ const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-0
const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds
+namespace
+{
+ bool operator == (const LLAssetStorage::LLGetAssetCallback &lhs, const LLAssetStorage::LLGetAssetCallback &rhs)
+ {
+ auto fnPtrLhs = lhs.target<LLAssetStorage::LLGetAssetCallback>();
+ auto fnPtrRhs = rhs.target<LLAssetStorage::LLGetAssetCallback>();
+ if (fnPtrLhs && fnPtrRhs)
+ return (*fnPtrLhs == *fnPtrRhs);
+ else if (!fnPtrLhs && !fnPtrRhs)
+ return true;
+ return false;
+ }
+
+// Rider: This is the general case of the operator declared above. The code compares the callback
+// passed into the LLAssetStorage functions to determine if there are duplicated requests for an
+// asset. Unfortunately std::function does not provide a direct way to compare two variables so
+// we define the operator here.
+// XCode is not very happy with the variadic temples in use below so we will just define the specific
+// case of comparing two LLGetAssetCallback objects since that is all we really use.
+//
+// template<typename T, typename... U>
+// bool operator == (const std::function<T(U...)> &a, const std::function <T(U...)> &b)
+// {
+// typedef T(fnType)(U...);
+//
+// auto fnPtrA = a.target<T(*)(U...)>();
+// auto fnPtrB = b.target<T(*)(U...)>();
+// if (fnPtrA && fnPtrB)
+// return (*fnPtrA == *fnPtrB);
+// else if (!fnPtrA && !fnPtrB)
+// return true;
+// return false;
+// }
+
+}
+
///----------------------------------------------------------------------------
/// LLAssetInfo
///----------------------------------------------------------------------------
@@ -160,7 +196,7 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )
LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type)
: mUUID(uuid),
mType(type),
- mDownCallback(NULL),
+ mDownCallback(),
mUserData(NULL),
mHost(),
mIsTemp(FALSE),
@@ -191,7 +227,7 @@ LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy()
LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
: LLBaseDownloadRequest(uuid, type),
- mUpCallback( NULL ),
+ mUpCallback(),
mInfoCallback( NULL ),
mIsLocal(FALSE),
mIsUserWaiting(FALSE),
@@ -449,7 +485,7 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
// IW - uuid is passed by value to avoid side effects, please don't re-add &
void LLAssetStorage::getAssetData(const LLUUID uuid,
LLAssetType::EType type,
- LLGetAssetCallback callback,
+ LLAssetStorage::LLGetAssetCallback callback,
void *user_data,
BOOL is_priority)
{
@@ -496,7 +532,11 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
BOOL exists = mVFS->getExists(uuid, type);
LLVFile file(mVFS, uuid, type);
U32 size = exists ? file.getSize() : 0;
-
+
+// LAPRAS TESTING
+// if (type == LLAssetType::AT_SETTINGS)
+// size = 0;
+
if (size > 0)
{
// we've already got the file
@@ -1326,9 +1366,13 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
iter != mPendingDownloads.end(); )
{
LLAssetRequest* tmp = *iter++;
+
+ //void(*const* cbptr)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)
+ auto cbptr = tmp->mDownCallback.target<void(*)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
+
if (type == tmp->getType() &&
uuid == tmp->getUUID() &&
- legacyGetDataCallback == tmp->mDownCallback &&
+ (cbptr && (*cbptr == legacyGetDataCallback)) &&
callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback &&
user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
{
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 33b88473b9..c799d8eefc 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -28,6 +28,7 @@
#ifndef LL_LLASSETSTORAGE_H
#define LL_LLASSETSTORAGE_H
#include <string>
+#include <functional>
#include "lluuid.h"
#include "lltimer.h"
@@ -59,6 +60,14 @@ const int LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE = -4;
const int LL_ERR_INSUFFICIENT_PERMISSIONS = -5;
const int LL_ERR_PRICE_MISMATCH = -23018;
+// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
+// future project would be to convert these to C++ callables (std::function<>) so that
+// we can use bind and remove the userData parameter.
+//
+typedef std::function<void(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback;
+typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> LLStoreAssetCallback;
+
+
class LLAssetInfo
{
protected:
@@ -110,7 +119,8 @@ protected:
LLAssetType::EType mType;
public:
- void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
+ LLGetAssetCallback mDownCallback;
+// void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
void *mUserData;
LLHost mHost;
@@ -131,7 +141,8 @@ public:
virtual LLBaseDownloadRequest* getCopy();
- void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);
+ LLStoreAssetCallback mUpCallback;
+// void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);
void (*mInfoCallback)(LLAssetInfo *, void *, S32);
BOOL mIsLocal;
@@ -182,12 +193,7 @@ protected:
// Map of known bad assets
typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
-// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
-// future project would be to convert these to C++ callables (std::function<>) so that
-// we can use bind and remove the userData parameter.
-//
-typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
- LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
+
class LLAssetStorage
{
@@ -195,7 +201,8 @@ public:
// VFS member is public because static child methods need it :(
LLVFS *mVFS;
LLVFS *mStaticVFS;
- typedef void (*LLStoreAssetCallback)(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status);
+ typedef ::LLStoreAssetCallback LLStoreAssetCallback;
+ typedef ::LLGetAssetCallback LLGetAssetCallback;
enum ERequestType
{
@@ -377,8 +384,8 @@ protected:
void _cleanupRequests(BOOL all, S32 error);
void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status);
- virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type,
- void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+ virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback,
+// void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
void *user_data, BOOL duplicate,
BOOL is_priority) = 0;
@@ -424,7 +431,7 @@ class LLLegacyAssetRequest
{
public:
void (*mDownCallback)(const char *, const LLUUID&, void *, S32, LLExtStat);
- LLAssetStorage::LLStoreAssetCallback mUpCallback;
+ LLStoreAssetCallback mUpCallback;
void *mUserData;
};
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index 8dbe2f8411..8baa2e328b 100644
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -543,7 +543,7 @@ void LLCircuitData::checkPeriodTime()
mBytesOutLastPeriod = mBytesOutThisPeriod;
mBytesInThisPeriod = S32Bytes(0);
mBytesOutThisPeriod = S32Bytes(0);
- mLastPeriodLength = period_length;
+ mLastPeriodLength = F32Seconds::convert(period_length);
mPeriodTime = mt_sec;
}
@@ -1378,8 +1378,8 @@ F32Milliseconds LLCircuitData::getPingInTransitTime()
if (mPingsInTransit)
{
- time_since_ping_was_sent = ((mPingsInTransit*mHeartbeatInterval - F32Seconds(1))
- + (LLMessageSystem::getMessageTimeSeconds() - mPingTime));
+ time_since_ping_was_sent = F32Milliseconds::convert(((mPingsInTransit*mHeartbeatInterval - F32Seconds(1))
+ + (LLMessageSystem::getMessageTimeSeconds() - mPingTime)));
}
return time_since_ping_was_sent;
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index d3791ef4d1..a0c87b65cc 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -54,6 +54,9 @@ const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7);
// All content wiped once per night
const U64 REGION_FLAGS_SANDBOX = (1 << 8);
+
+const U64 REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE = (1 << 9);
+
const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies
const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13);
const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 1ae8a6ac15..6e5923862b 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -1375,7 +1375,9 @@ char const* const _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getIn
char const* const _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock");
char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getInstance()->getString("RegionAllowAccessBlock");
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
-
+char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock");
+char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion");
+char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
char const* const _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 7910fde305..30763d426e 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -1375,6 +1375,9 @@ extern char const* const _PREHASH_RegionDenyAgeUnverified;
extern char const* const _PREHASH_AgeVerificationBlock;
extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
+extern char const* const _PREHASH_ParcelEnvironmentBlock;
+extern char const* const _PREHASH_ParcelEnvironmentVersion;
+extern char const* const _PREHASH_RegionAllowEnvironmentOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
extern char const* const _PREHASH_FaceIndex;
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index e24d222cb6..594793cf56 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -253,7 +253,7 @@ void LLPluginProcessChild::sleep(F64 seconds)
}
else
{
- ms_sleep((int)(seconds * 1000.0f));
+ ms_sleep((int)(seconds * 1000.0f));
}
}
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 07a0d8c402..bcb5a847f6 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -13,6 +13,7 @@ include(LLVFS)
include(LLWindow)
include(LLXML)
include(LLVFS)
+include(Atmosphere)
include_directories(
${FREETYPE_INCLUDE_DIRS}
@@ -24,6 +25,7 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
+ ${ATMOSPHERE_INCLUDE_DIR}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -31,6 +33,7 @@ include_directories(SYSTEM
)
set(llrender_SOURCE_FILES
+ llatmosphere.cpp
llcubemap.cpp
llfontbitmapcache.cpp
llfontfreetype.cpp
@@ -57,6 +60,7 @@ set(llrender_SOURCE_FILES
set(llrender_HEADER_FILES
CMakeLists.txt
+ llatmosphere.h
llcubemap.h
llfontgl.h
llfontfreetype.h
@@ -105,7 +109,9 @@ if (BUILD_HEADLESS)
${LLXML_LIBRARIES}
${LLVFS_LIBRARIES}
${LLWINDOW_HEADLESS_LIBRARIES}
- ${OPENGL_HEADLESS_LIBRARIES})
+ ${LIBATMOSPHERE_LIBRARIES}
+ ${OPENGL_HEADLESS_LIBRARIES}
+ )
endif (BUILD_HEADLESS)
@@ -128,5 +134,7 @@ target_link_libraries(llrender
${LLVFS_LIBRARIES}
${LLWINDOW_LIBRARIES}
${FREETYPE_LIBRARIES}
- ${OPENGL_LIBRARIES})
+ ${LIBATMOSPHERE_LIBRARIES}
+ ${OPENGL_LIBRARIES}
+ )
diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp
new file mode 100644
index 0000000000..12c6685354
--- /dev/null
+++ b/indra/llrender/llatmosphere.cpp
@@ -0,0 +1,349 @@
+/**
+ * @file llatmosphere.cpp
+ * @brief LLAtmosphere integration impl
+ *
+ * $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 "linden_common.h"
+
+#include "llatmosphere.h"
+#include "llfasttimer.h"
+#include "llsys.h"
+#include "llglheaders.h"
+#include "llrender.h"
+#include "llshadermgr.h"
+#include "llglslshader.h"
+
+LLAtmosphere* gAtmosphere = nullptr;
+
+// Values from "Reference Solar Spectral Irradiance: ASTM G-173", ETR column
+// (see http://rredc.nrel.gov/solar/spectra/am1.5/ASTMG173/ASTMG173.html),
+// summed and averaged in each bin (e.g. the value for 360nm is the average
+// of the ASTM G-173 values for all wavelengths between 360 and 370nm).
+// Values in W.m^-2.
+const int kLambdaMin = 360;
+const int kLambdaMax = 830;
+const double kSolarIrradiance[48] = {
+ 1.11776, 1.14259, 1.01249, 1.14716, 1.72765, 1.73054, 1.6887, 1.61253,
+ 1.91198, 2.03474, 2.02042, 2.02212, 1.93377, 1.95809, 1.91686, 1.8298,
+ 1.8685, 1.8931, 1.85149, 1.8504, 1.8341, 1.8345, 1.8147, 1.78158, 1.7533,
+ 1.6965, 1.68194, 1.64654, 1.6048, 1.52143, 1.55622, 1.5113, 1.474, 1.4482,
+ 1.41018, 1.36775, 1.34188, 1.31429, 1.28303, 1.26758, 1.2367, 1.2082,
+ 1.18737, 1.14683, 1.12362, 1.1058, 1.07124, 1.04992
+};
+
+// Values from http://www.iup.uni-bremen.de/gruppen/molspec/databases/
+// referencespectra/o3spectra2011/index.html for 233K, summed and averaged in
+// each bin (e.g. the value for 360nm is the average of the original values
+// for all wavelengths between 360 and 370nm). Values in m^2.
+const double kOzoneCrossSection[48] = {
+ 1.18e-27, 2.182e-28, 2.818e-28, 6.636e-28, 1.527e-27, 2.763e-27, 5.52e-27,
+ 8.451e-27, 1.582e-26, 2.316e-26, 3.669e-26, 4.924e-26, 7.752e-26, 9.016e-26,
+ 1.48e-25, 1.602e-25, 2.139e-25, 2.755e-25, 3.091e-25, 3.5e-25, 4.266e-25,
+ 4.672e-25, 4.398e-25, 4.701e-25, 5.019e-25, 4.305e-25, 3.74e-25, 3.215e-25,
+ 2.662e-25, 2.238e-25, 1.852e-25, 1.473e-25, 1.209e-25, 9.423e-26, 7.455e-26,
+ 6.566e-26, 5.105e-26, 4.15e-26, 4.228e-26, 3.237e-26, 2.451e-26, 2.801e-26,
+ 2.534e-26, 1.624e-26, 1.465e-26, 2.078e-26, 1.383e-26, 7.105e-27
+};
+
+// From https://en.wikipedia.org/wiki/Dobson_unit, in molecules.m^-2.
+const double kDobsonUnit = 2.687e20;
+// Maximum number density of ozone molecules, in m^-3 (computed so at to get
+// 300 Dobson units of ozone - for this we divide 300 DU by the integral of
+// the ozone density profile defined below, which is equal to 15km).
+const double kMaxOzoneNumberDensity = 300.0 * kDobsonUnit / 15000.0;
+const double kRayleigh = 1.24062e-6;
+const double kRayleighScaleHeight = 8000.0;
+const double kMieScaleHeight = 1200.0;
+const double kMieAngstromAlpha = 0.0;
+const double kMieAngstromBeta = 5.328e-3;
+const double kMieSingleScatteringAlbedo = 0.9;
+const double kGroundAlbedo = 0.1;
+
+const double max_sun_zenith_angle = F_PI * 2.0 / 3.0;
+
+AtmosphericModelSettings::AtmosphericModelSettings()
+ : m_skyBottomRadius(6360.0f)
+ , m_skyTopRadius(6420.0f)
+ , m_sunArcRadians(0.00045f)
+ , m_mieAnisotropy(0.8f)
+{
+ atmosphere::DensityProfileLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0);
+ atmosphere::DensityProfileLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0);
+
+ m_rayleighProfile.push_back(rayleigh_density);
+ m_mieProfile.push_back(mie_density);
+
+ // Density profile increasing linearly from 0 to 1 between 10 and 25km, and
+ // decreasing linearly from 1 to 0 between 25 and 40km. This is an approximate
+ // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/
+ // Documents/Introduction%20to%20atmospheric%20chemistry.pdf (page 10).
+ m_absorptionProfile.push_back(atmosphere::DensityProfileLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0));
+ m_absorptionProfile.push_back(atmosphere::DensityProfileLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0));
+}
+
+AtmosphericModelSettings::AtmosphericModelSettings(
+ DensityProfile& rayleighProfile,
+ DensityProfile& mieProfile,
+ DensityProfile& absorptionProfile)
+: m_skyBottomRadius(6360.0f)
+, m_skyTopRadius(6420.0f)
+, m_rayleighProfile(rayleighProfile)
+, m_mieProfile(mieProfile)
+, m_absorptionProfile(absorptionProfile)
+, m_sunArcRadians(0.00045f)
+, m_mieAnisotropy(0.8f)
+{
+}
+
+AtmosphericModelSettings::AtmosphericModelSettings(
+ F32 skyBottomRadius,
+ F32 skyTopRadius,
+ DensityProfile& rayleighProfile,
+ DensityProfile& mieProfile,
+ DensityProfile& absorptionProfile,
+ F32 sunArcRadians,
+ F32 mieAniso)
+: m_skyBottomRadius(skyBottomRadius)
+, m_skyTopRadius(skyTopRadius)
+, m_rayleighProfile(rayleighProfile)
+, m_mieProfile(mieProfile)
+, m_absorptionProfile(absorptionProfile)
+, m_sunArcRadians(sunArcRadians)
+, m_mieAnisotropy(mieAniso)
+{
+}
+
+bool AtmosphericModelSettings::operator==(const AtmosphericModelSettings& rhs) const
+{
+ if (m_skyBottomRadius != rhs.m_skyBottomRadius)
+ {
+ return false;
+ }
+
+ if (m_skyTopRadius != rhs.m_skyTopRadius)
+ {
+ return false;
+ }
+
+ if (m_sunArcRadians != rhs.m_sunArcRadians)
+ {
+ return false;
+ }
+
+ if (m_mieAnisotropy != rhs.m_mieAnisotropy)
+ {
+ return false;
+ }
+
+ if (m_rayleighProfile != rhs.m_rayleighProfile)
+ {
+ return false;
+ }
+
+ if (m_mieProfile != rhs.m_mieProfile)
+ {
+ return false;
+ }
+
+ if (m_absorptionProfile != rhs.m_absorptionProfile)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLAtmosphere::initClass()
+{
+ if (!gAtmosphere)
+ {
+ gAtmosphere = new LLAtmosphere;
+ }
+}
+
+void LLAtmosphere::cleanupClass()
+{
+ if(gAtmosphere)
+ {
+ delete gAtmosphere;
+ }
+ gAtmosphere = NULL;
+}
+
+LLAtmosphere::LLAtmosphere()
+{
+ for (int l = kLambdaMin; l <= kLambdaMax; l += 10)
+ {
+ double lambda = static_cast<double>(l) * 1e-3; // micro-meters
+ double mie = kMieAngstromBeta / kMieScaleHeight * pow(lambda, -kMieAngstromAlpha);
+ m_wavelengths.push_back(l);
+ m_solar_irradiance.push_back(kSolarIrradiance[(l - kLambdaMin) / 10]);
+ m_rayleigh_scattering.push_back(kRayleigh * pow(lambda, -4));
+ m_mie_scattering.push_back(mie * kMieSingleScatteringAlbedo);
+ m_mie_extinction.push_back(mie);
+ m_absorption_extinction.push_back(kMaxOzoneNumberDensity * kOzoneCrossSection[(l - kLambdaMin) / 10]);
+ m_ground_albedo.push_back(kGroundAlbedo);
+ }
+
+ AtmosphericModelSettings defaults;
+ configureAtmosphericModel(defaults);
+}
+
+LLAtmosphere::~LLAtmosphere()
+{
+ // Cease referencing textures from atmosphere::model from our LLGLTextures wrappers for same.
+ if (m_transmittance)
+ {
+ m_transmittance->setTexName(0);
+ }
+
+ if (m_scattering)
+ {
+ m_scattering->setTexName(0);
+ }
+
+ if (m_mie_scatter_texture)
+ {
+ m_mie_scatter_texture->setTexName(0);
+ }
+
+ delete m_model;
+ m_model = nullptr;
+}
+
+bool LLAtmosphere::configureAtmosphericModel(AtmosphericModelSettings& settings)
+{
+ if ((m_model != nullptr) && (settings == m_settings))
+ {
+ return true;
+ }
+
+ if (m_model)
+ {
+ delete m_model;
+ }
+ m_model = nullptr;
+
+ getTransmittance()->setTexName(0);
+ getScattering()->setTexName(0);
+ getMieScattering()->setTexName(0);
+ getIlluminance()->setTexName(0);
+
+ // Init libatmosphere model
+ m_model = new atmosphere::Model(
+ m_config,
+ m_wavelengths,
+ m_solar_irradiance,
+ settings.m_sunArcRadians,
+ settings.m_skyBottomRadius * 1000.0f,
+ settings.m_skyTopRadius * 1000.0f,
+ settings.m_rayleighProfile,
+ m_rayleigh_scattering,
+ settings.m_mieProfile,
+ m_mie_scattering,
+ m_mie_extinction,
+ settings.m_mieAnisotropy,
+ settings.m_absorptionProfile,
+ m_absorption_extinction,
+ m_ground_albedo,
+ max_sun_zenith_angle,
+ 1000.0,
+ 3,
+ false, // do not combine_scattering...we want indep textures
+ false, // use 32F for 2d textures to avoid artifacts
+ true); // use 16F for 3d textures to reduce footprint
+
+ if (m_model)
+ {
+ m_model->Init(m_config, m_textures);
+ getTransmittance()->setTexName(m_textures.transmittance_texture);
+ getScattering()->setTexName(m_textures.scattering_texture);
+ getMieScattering()->setTexName(m_textures.single_mie_scattering_texture);
+ getIlluminance()->setTexName(m_textures.illuminance_texture);
+ m_settings = settings;
+ }
+
+ return m_model != nullptr;
+}
+
+LLGLTexture* LLAtmosphere::getTransmittance()
+{
+ if (!m_transmittance)
+ {
+ m_transmittance = new LLGLTexture;
+ m_transmittance->generateGLTexture();
+ m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
+ m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
+ m_transmittance->setExplicitFormat(GL_RGB32F_ARB, GL_RGB, GL_FLOAT);
+ m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
+ }
+ return m_transmittance;
+}
+
+LLGLTexture* LLAtmosphere::getScattering()
+{
+ if (!m_scattering)
+ {
+ m_scattering = new LLGLTexture;
+ m_scattering->generateGLTexture();
+ m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
+ m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
+ m_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT);
+ m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D);
+ }
+ return m_scattering;
+}
+
+LLGLTexture* LLAtmosphere::getMieScattering()
+{
+ if (!m_mie_scatter_texture)
+ {
+ m_mie_scatter_texture = new LLGLTexture;
+ m_mie_scatter_texture->generateGLTexture();
+ m_mie_scatter_texture->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
+ m_mie_scatter_texture->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
+ m_mie_scatter_texture->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT);
+ m_mie_scatter_texture->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D);
+ }
+ return m_mie_scatter_texture;
+}
+
+LLGLTexture* LLAtmosphere::getIlluminance()
+{
+ if (!m_illuminance)
+ {
+ m_illuminance = new LLGLTexture;
+ m_illuminance->generateGLTexture();
+ m_illuminance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
+ m_illuminance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
+ m_illuminance->setExplicitFormat(GL_RGB32F_ARB, GL_RGB, GL_FLOAT);
+ m_illuminance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
+ }
+ return m_illuminance;
+}
+
+GLhandleARB LLAtmosphere::getAtmosphericShaderForLink() const
+{
+ return m_model ? m_model->GetShader() : 0;
+}
diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h
new file mode 100644
index 0000000000..a010803595
--- /dev/null
+++ b/indra/llrender/llatmosphere.h
@@ -0,0 +1,118 @@
+/**
+ * @file llatmosphere.h
+ * @brief LLAtmosphere class for integration with libatmosphere
+ *
+ * $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_ATMOSPHERE_H
+#define LL_ATMOSPHERE_H
+
+#include "llglheaders.h"
+#include "llgltexture.h"
+#include "libatmosphere/model.h"
+
+typedef std::vector<atmosphere::DensityProfileLayer> DensityProfile;
+
+class AtmosphericModelSettings
+{
+public:
+ AtmosphericModelSettings();
+
+ AtmosphericModelSettings(
+ DensityProfile& rayleighProfile,
+ DensityProfile& mieProfile,
+ DensityProfile& absorptionProfile);
+
+ AtmosphericModelSettings(
+ F32 skyBottomRadius,
+ F32 skyTopRadius,
+ DensityProfile& rayleighProfile,
+ DensityProfile& mieProfile,
+ DensityProfile& absorptionProfile,
+ F32 sunArcRadians,
+ F32 mieAniso);
+
+ bool operator==(const AtmosphericModelSettings& rhs) const;
+
+ F32 m_skyBottomRadius;
+ F32 m_skyTopRadius;
+ DensityProfile m_rayleighProfile;
+ DensityProfile m_mieProfile;
+ DensityProfile m_absorptionProfile;
+ F32 m_sunArcRadians;
+ F32 m_mieAnisotropy;
+};
+
+class LLAtmosphere
+{
+public:
+ LLAtmosphere();
+ ~LLAtmosphere();
+
+ static void initClass();
+ static void cleanupClass();
+
+ const LLAtmosphere& operator=(const LLAtmosphere& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
+
+ LLGLTexture* getTransmittance();
+ LLGLTexture* getScattering();
+ LLGLTexture* getMieScattering();
+ LLGLTexture* getIlluminance();
+
+ GLhandleARB getAtmosphericShaderForLink() const;
+
+ bool configureAtmosphericModel(AtmosphericModelSettings& settings);
+
+protected:
+ LLAtmosphere(const LLAtmosphere& rhs)
+ {
+ *this = rhs;
+ }
+
+ atmosphere::ModelConfig m_config;
+ atmosphere::PrecomputedTextures m_textures;
+ atmosphere::Model* m_model = nullptr;
+
+ LLPointer<LLGLTexture> m_transmittance;
+ LLPointer<LLGLTexture> m_scattering;
+ LLPointer<LLGLTexture> m_mie_scatter_texture;
+ LLPointer<LLGLTexture> m_illuminance;
+
+ std::vector<double> m_wavelengths;
+ std::vector<double> m_solar_irradiance;
+ std::vector<double> m_rayleigh_scattering;
+ std::vector<double> m_mie_scattering;
+ std::vector<double> m_mie_extinction;
+ std::vector<double> m_absorption_extinction;
+ std::vector<double> m_ground_albedo;
+
+ AtmosphericModelSettings m_settings;
+};
+
+extern LLAtmosphere* gAtmosphere;
+
+#endif // LL_ATMOSPHERE_H
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 35b6951779..2f78b6e104 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1352,8 +1352,8 @@ void LLGLManager::initExtensions()
// nSight doesn't support use of ARB funcs that have been normalized in the API
if (!LLRender::sNsightDebugSupport)
{
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
+ glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
+ glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
}
else
{
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4702042ab9..c03d33080f 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -84,6 +84,9 @@ LLShaderFeatures::LLShaderFeatures()
, hasObjectSkinning(false)
, hasAtmospherics(false)
, hasGamma(false)
+ , hasSrgb(false)
+ , encodesNormal(false)
+ , decodesNormal(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
@@ -402,6 +405,11 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
mDefines["OLD_SELECT"] = "1";
#endif
+ if (mExtraLinkObject)
+ {
+ attachObject(mExtraLinkObject);
+ }
+
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@@ -561,7 +569,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
mAttribute[i] = index;
#endif
mAttributeMask |= 1 << i;
- LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
+ LL_DEBUGS("ShaderUniform") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
}
if (attributes != NULL)
@@ -573,7 +581,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
if (index != -1)
{
mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
- LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
+ LL_DEBUGS("ShaderUniform") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
}
}
@@ -658,7 +666,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
mUniformNameMap[location] = name;
mUniformMap[hashedName] = location;
- LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
+ LL_DEBUGS("ShaderUniform") << "Uniform " << name << " is at location " << location << LL_ENDL;
//find the index of this uniform
for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
@@ -706,7 +714,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
glUniform1iARB(location, mActiveTextureChannels);
- LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
+ LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
return mActiveTextureChannels++;
}
return -1;
@@ -759,18 +767,19 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
+ S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
std::set<S32> skip_index;
- if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))
+ if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
{
GLenum type;
GLsizei length;
GLint size = -1;
char name[1024];
- diffuseMap = specularMap = bumpMap = environmentMap = -1;
+ diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
for (S32 i = 0; i < activeCount; i++)
{
@@ -790,12 +799,6 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
continue;
}
- if (-1 == specularMap && std::string(name) == "specularMap")
- {
- specularMap = i;
- continue;
- }
-
if (-1 == bumpMap && std::string(name) == "bumpMap")
{
bumpMap = i;
@@ -807,6 +810,12 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
environmentMap = i;
continue;
}
+
+ if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
+ {
+ altDiffuseMap = i;
+ continue;
+ }
}
bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
@@ -849,7 +858,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
unbind();
- LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
+ LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
return res;
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index b56b914013..0934ceba30 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -48,6 +48,9 @@ public:
bool hasObjectSkinning;
bool hasAtmospherics;
bool hasGamma;
+ bool hasSrgb;
+ bool encodesNormal;
+ bool decodesNormal;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
@@ -211,6 +214,8 @@ public:
std::vector<U32> mTextureMagFilter;
std::vector<U32> mTextureMinFilter;
+ GLhandleARB mExtraLinkObject = 0;
+
private:
void unloadInternal();
};
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 3a6eebebba..e9a39d8acb 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -30,20 +30,20 @@
// static
S32 LLGLTexture::getTotalNumOfCategories()
{
- return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
+ return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2;
}
// static
//index starts from zero.
S32 LLGLTexture::getIndexFromCategory(S32 category)
{
- return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
+ return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1;
}
//static
S32 LLGLTexture::getCategoryFromIndex(S32 index)
{
- return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
+ return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1;
}
LLGLTexture::LLGLTexture(BOOL usemipmaps)
@@ -55,19 +55,19 @@ LLGLTexture::LLGLTexture(BOOL usemipmaps)
LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
{
init();
- mFullWidth = width ;
- mFullHeight = height ;
+ mFullWidth = width;
+ mFullHeight = height;
mUseMipMaps = usemipmaps;
- mComponents = components ;
+ mComponents = components;
setTexelsPerImage();
}
LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
{
init();
- mUseMipMaps = usemipmaps ;
+ mUseMipMaps = usemipmaps;
// Create an empty image of the specified size and width
- mGLTexturep = new LLImageGL(raw, usemipmaps) ;
+ mGLTexturep = new LLImageGL(raw, usemipmaps);
}
LLGLTexture::~LLGLTexture()
@@ -81,13 +81,13 @@ void LLGLTexture::init()
mFullWidth = 0;
mFullHeight = 0;
- mTexelsPerImage = 0 ;
- mUseMipMaps = FALSE ;
- mComponents = 0 ;
+ mTexelsPerImage = 0;
+ mUseMipMaps = FALSE;
+ mComponents = 0;
- mTextureState = NO_DELETE ;
+ mTextureState = NO_DELETE;
mDontDiscard = FALSE;
- mNeedsGLTexture = FALSE ;
+ mNeedsGLTexture = FALSE;
}
void LLGLTexture::cleanup()
@@ -111,287 +111,301 @@ void LLGLTexture::setBoostLevel(S32 level)
{
if(mBoostLevel != level)
{
- mBoostLevel = level ;
+ mBoostLevel = level;
if(mBoostLevel != LLGLTexture::BOOST_NONE
&& mBoostLevel != LLGLTexture::BOOST_ICON)
{
- setNoDelete() ;
+ setNoDelete();
}
}
}
void LLGLTexture::forceActive()
{
- mTextureState = ACTIVE ;
+ mTextureState = ACTIVE;
}
void LLGLTexture::setActive()
{
if(mTextureState != NO_DELETE)
{
- mTextureState = ACTIVE ;
+ mTextureState = ACTIVE;
}
}
//set the texture to stay in memory
void LLGLTexture::setNoDelete()
{
- mTextureState = NO_DELETE ;
+ mTextureState = NO_DELETE;
}
void LLGLTexture::generateGLTexture()
{
if(mGLTexturep.isNull())
{
- mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
+ mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps);
}
}
LLImageGL* LLGLTexture::getGLTexture() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep ;
+ return mGLTexturep;
}
BOOL LLGLTexture::createGLTexture()
{
if(mGLTexturep.isNull())
{
- generateGLTexture() ;
+ generateGLTexture();
}
- return mGLTexturep->createGLTexture() ;
+ return mGLTexturep->createGLTexture();
}
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
+ BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category);
if(ret)
{
- mFullWidth = mGLTexturep->getCurrentWidth() ;
- mFullHeight = mGLTexturep->getCurrentHeight() ;
- mComponents = mGLTexturep->getComponents() ;
+ mFullWidth = mGLTexturep->getCurrentWidth();
+ mFullHeight = mGLTexturep->getCurrentHeight();
+ mComponents = mGLTexturep->getComponents();
setTexelsPerImage();
}
- return ret ;
+ return ret;
}
void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
+ mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
}
void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
{
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setAddressMode(mode) ;
+ llassert(mGLTexturep.notNull());
+ mGLTexturep->setAddressMode(mode);
}
void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
{
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setFilteringOption(option) ;
+ llassert(mGLTexturep.notNull());
+ mGLTexturep->setFilteringOption(option);
}
//virtual
S32 LLGLTexture::getWidth(S32 discard_level) const
{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getWidth(discard_level) ;
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->getWidth(discard_level);
}
//virtual
S32 LLGLTexture::getHeight(S32 discard_level) const
{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getHeight(discard_level) ;
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->getHeight(discard_level);
}
S32 LLGLTexture::getMaxDiscardLevel() const
{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getMaxDiscardLevel() ;
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->getMaxDiscardLevel();
}
S32 LLGLTexture::getDiscardLevel() const
{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getDiscardLevel() ;
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->getDiscardLevel();
}
S8 LLGLTexture::getComponents() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getComponents() ;
+ return mGLTexturep->getComponents();
}
LLGLuint LLGLTexture::getTexName() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getTexName() ;
+ return mGLTexturep->getTexName();
}
BOOL LLGLTexture::hasGLTexture() const
{
if(mGLTexturep.notNull())
{
- return mGLTexturep->getHasGLTexture() ;
+ return mGLTexturep->getHasGLTexture();
}
- return FALSE ;
+ return FALSE;
}
BOOL LLGLTexture::getBoundRecently() const
{
if(mGLTexturep.notNull())
{
- return mGLTexturep->getBoundRecently() ;
+ return mGLTexturep->getBoundRecently();
}
- return FALSE ;
+ return FALSE;
}
LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTarget() ;
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->getTarget();
}
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
+ return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height);
}
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
+ return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height);
}
void LLGLTexture::setGLTextureCreated (bool initialized)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- mGLTexturep->setGLTextureCreated (initialized) ;
+ mGLTexturep->setGLTextureCreated (initialized);
}
void LLGLTexture::setCategory(S32 category)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
+
+ mGLTexturep->setCategory(category);
+}
- mGLTexturep->setCategory(category) ;
+void LLGLTexture::setTexName(LLGLuint texName)
+{
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->setTexName(texName);
+}
+
+void LLGLTexture::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
+{
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->setTarget(target, bind_target);
}
LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getAddressMode() ;
+ return mGLTexturep->getAddressMode();
}
S32Bytes LLGLTexture::getTextureMemory() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->mTextureMemory ;
+ return mGLTexturep->mTextureMemory;
}
LLGLenum LLGLTexture::getPrimaryFormat() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getPrimaryFormat() ;
+ return mGLTexturep->getPrimaryFormat();
}
BOOL LLGLTexture::getIsAlphaMask() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getIsAlphaMask() ;
+ return mGLTexturep->getIsAlphaMask();
}
BOOL LLGLTexture::getMask(const LLVector2 &tc)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getMask(tc) ;
+ return mGLTexturep->getMask(tc);
}
F32 LLGLTexture::getTimePassedSinceLastBound()
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getTimePassedSinceLastBound() ;
+ return mGLTexturep->getTimePassedSinceLastBound();
}
BOOL LLGLTexture::getMissed() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getMissed() ;
+ return mGLTexturep->getMissed();
}
BOOL LLGLTexture::isJustBound() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->isJustBound() ;
+ return mGLTexturep->isJustBound();
}
void LLGLTexture::forceUpdateBindStats(void) const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->forceUpdateBindStats() ;
+ return mGLTexturep->forceUpdateBindStats();
}
U32 LLGLTexture::getTexelsInAtlas() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getTexelsInAtlas() ;
+ return mGLTexturep->getTexelsInAtlas();
}
U32 LLGLTexture::getTexelsInGLTexture() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getTexelsInGLTexture() ;
+ return mGLTexturep->getTexelsInGLTexture();
}
BOOL LLGLTexture::isGLTextureCreated() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->isGLTextureCreated() ;
+ return mGLTexturep->isGLTextureCreated();
}
S32 LLGLTexture::getDiscardLevelInAtlas() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull());
- return mGLTexturep->getDiscardLevelInAtlas() ;
+ return mGLTexturep->getDiscardLevelInAtlas();
}
void LLGLTexture::destroyGLTexture()
{
if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
{
- mGLTexturep->destroyGLTexture() ;
- mTextureState = DELETED ;
+ mGLTexturep->destroyGLTexture();
+ mTextureState = DELETED;
}
}
void LLGLTexture::setTexelsPerImage()
{
- S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
- S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
- mTexelsPerImage = (F32)fullwidth * fullheight;
+ U32 fullwidth = llmin(mFullWidth, (U32)MAX_IMAGE_SIZE_DEFAULT);
+ U32 fullheight = llmin(mFullHeight, (U32)MAX_IMAGE_SIZE_DEFAULT);
+ mTexelsPerImage = (U32)fullwidth * fullheight;
}
+static LLUUID sStubUUID;
+const LLUUID& LLGLTexture::getID() const { return sStubUUID; }
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 70610d9626..bdaed05591 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -104,7 +104,7 @@ public:
virtual void dump(); // debug info to LL_INFOS()
- virtual const LLUUID& getID() const = 0;
+ virtual const LLUUID& getID() const;
void setBoostLevel(S32 level);
S32 getBoostLevel() { return mBoostLevel; }
@@ -133,6 +133,8 @@ public:
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
void setGLTextureCreated (bool initialized);
void setCategory(S32 category) ;
+ void setTexName(LLGLuint); // for forcing w/ externally created textures only
+ void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
S32 getMaxDiscardLevel() const;
@@ -179,11 +181,11 @@ protected:
protected:
S32 mBoostLevel; // enum describing priority level
- S32 mFullWidth;
- S32 mFullHeight;
+ U32 mFullWidth;
+ U32 mFullHeight;
BOOL mUseMipMaps;
S8 mComponents;
- F32 mTexelsPerImage; // Texels per image.
+ U32 mTexelsPerImage; // Texels per image.
mutable S8 mNeedsGLTexture;
//GL texture
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 40217b2e80..25ec493fa2 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -352,10 +352,9 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B
}
//----------------------------------------------------------------------------
-
LLImageGL::LLImageGL(BOOL usemipmaps)
: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0)
+ mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -365,7 +364,7 @@ LLImageGL::LLImageGL(BOOL usemipmaps)
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0)
+ mSaveData(0), mExternalTexture(FALSE)
{
llassert( components <= 4 );
init(usemipmaps);
@@ -376,7 +375,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0)
+ mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -386,12 +385,36 @@ LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
createGLTexture(0, imageraw);
}
+LLImageGL::LLImageGL(
+ LLGLuint texName,
+ U32 components,
+ LLGLenum target,
+ LLGLint formatInternal,
+ LLGLenum formatPrimary,
+ LLGLenum formatType,
+ LLTexUnit::eTextureAddressMode addressMode)
+ : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE)
+{
+ init(false);
+ mTexName = texName;
+ mTarget = target;
+ mComponents = components;
+ mAddressMode = addressMode;
+ mFormatType = formatType;
+ mFormatInternal = formatInternal;
+ mFormatPrimary = formatPrimary;
+}
+
+
LLImageGL::~LLImageGL()
{
- LLImageGL::cleanup();
- sImageList.erase(this);
- freePickMask();
- sCount--;
+ if (!mExternalTexture)
+ {
+ LLImageGL::cleanup();
+ sImageList.erase(this);
+ freePickMask();
+ sCount--;
+ }
}
void LLImageGL::init(BOOL usemipmaps)
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2be54be062..4f3d7eed0a 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -84,7 +84,10 @@ public:
LLImageGL(BOOL usemipmaps = TRUE);
LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
-
+
+ // For wrapping textures created via GL elsewhere with our API only. Use with caution.
+ LLImageGL(LLGLuint mTexName, U32 components, LLGLenum target, LLGLint formatInternal, LLGLenum formatPrimary, LLGLenum formatType, LLTexUnit::eTextureAddressMode addressMode);
+
protected:
virtual ~LLImageGL();
@@ -234,6 +237,8 @@ protected:
LLGLenum mFormatType;
BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
+ BOOL mExternalTexture;
+
// STATICS
public:
static std::set<LLImageGL*> sImageList;
@@ -279,6 +284,8 @@ public:
void setCategory(S32 category) {mCategory = category;}
S32 getCategory()const {return mCategory;}
+ void setTexName(GLuint texName) { mTexName = texName; }
+
//for debug use: show texture size distribution
//----------------------------------------
static S32 sCurTexSizeBar ;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 65d6181920..251c02dd77 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -59,7 +59,8 @@ static const GLenum sGLTextureType[] =
GL_TEXTURE_2D,
GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_CUBE_MAP_ARB,
- GL_TEXTURE_2D_MULTISAMPLE
+ GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_3D
};
static const GLint sGLAddressMode[] =
@@ -1190,6 +1191,7 @@ void LLRender::syncMatrices()
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
static glh::matrix4f cached_mvp;
+ static glh::matrix4f cached_inv_mdv;
static U32 cached_mvp_mdv_hash = 0xFFFFFFFF;
static U32 cached_mvp_proj_hash = 0xFFFFFFFF;
@@ -1203,12 +1205,18 @@ void LLRender::syncMatrices()
bool mvp_done = false;
U32 i = MM_MODELVIEW;
- if (mMatHash[i] != shader->mMatHash[i])
+ if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW])
{ //update modelview, normal, and MVP
- glh::matrix4f& mat = mMatrix[i][mMatIdx[i]];
+ glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
- shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m);
- shader->mMatHash[i] = mMatHash[i];
+ // if MDV has changed, update the cached inverse as well
+ if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW])
+ {
+ cached_inv_mdv = mat.inverse();
+ }
+
+ shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, mat.m);
+ shader->mMatHash[MM_MODELVIEW] = mMatHash[MM_MODELVIEW];
//update normal matrix
S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX);
@@ -1216,7 +1224,7 @@ void LLRender::syncMatrices()
{
if (cached_normal_hash != mMatHash[i])
{
- cached_normal = mat.inverse().transpose();
+ cached_normal = cached_inv_mdv.transpose();
cached_normal_hash = mMatHash[i];
}
@@ -1232,6 +1240,11 @@ void LLRender::syncMatrices()
shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat);
}
+ if (shader->getUniformLocation(LLShaderMgr::INVERSE_MODELVIEW_MATRIX))
+ {
+ shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, GL_FALSE, cached_inv_mdv.m);
+ }
+
//update MVP matrix
mvp_done = true;
loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
@@ -1251,14 +1264,21 @@ void LLRender::syncMatrices()
}
}
-
i = MM_PROJECTION;
- if (mMatHash[i] != shader->mMatHash[i])
+ if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION])
{ //update projection matrix, normal, and MVP
- glh::matrix4f& mat = mMatrix[i][mMatIdx[i]];
+ glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
- shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m);
- shader->mMatHash[i] = mMatHash[i];
+ // it would be nice to have this automatically track the state of the proj matrix
+ // but certain render paths require it to be mismatched *sigh*
+ //if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX))
+ //{
+ // glh::matrix4f inv_proj = mat.inverse();
+ // shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+ //}
+
+ shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m);
+ shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION];
if (!mvp_done)
{
@@ -1266,7 +1286,7 @@ void LLRender::syncMatrices()
S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
if (loc > -1)
{
- if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
+ if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
{
U32 mdv = MM_MODELVIEW;
cached_mvp = mat;
@@ -2331,3 +2351,85 @@ void LLRender::debugTexUnits(void)
LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
}
+
+
+glh::matrix4f copy_matrix(F32* src)
+{
+ glh::matrix4f ret;
+ ret.set_value(src);
+ return ret;
+}
+
+glh::matrix4f get_current_modelview()
+{
+ return copy_matrix(gGLModelView);
+}
+
+glh::matrix4f get_current_projection()
+{
+ return copy_matrix(gGLProjection);
+}
+
+glh::matrix4f get_last_modelview()
+{
+ return copy_matrix(gGLLastModelView);
+}
+
+glh::matrix4f get_last_projection()
+{
+ return copy_matrix(gGLLastProjection);
+}
+
+void copy_matrix(const glh::matrix4f& src, F32* dst)
+{
+ for (U32 i = 0; i < 16; i++)
+ {
+ dst[i] = src.m[i];
+ }
+}
+
+void set_current_modelview(const glh::matrix4f& mat)
+{
+ copy_matrix(mat, gGLModelView);
+}
+
+void set_current_projection(glh::matrix4f& mat)
+{
+ 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;
+}
+
+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);
+
+}
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 32bb728d8a..62cd526550 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -61,10 +61,11 @@ public:
typedef enum
{
TT_TEXTURE = 0, // Standard 2D Texture
- TT_RECT_TEXTURE, // Non power of 2 texture
- TT_CUBE_MAP, // 6-sided cube map texture
+ TT_RECT_TEXTURE, // Non power of 2 texture
+ TT_CUBE_MAP, // 6-sided cube map texture
TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
- TT_NONE // No texture type is currently enabled
+ TT_TEXTURE_3D, // standard 3D Texture
+ TT_NONE, // No texture type is currently enabled
} eTextureType;
typedef enum
@@ -264,10 +265,11 @@ public:
enum eTexIndex
{
- DIFFUSE_MAP = 0,
- NORMAL_MAP,
- SPECULAR_MAP,
- NUM_TEXTURE_CHANNELS,
+ DIFFUSE_MAP = 0,
+ ALTERNATE_DIFFUSE_MAP = 1,
+ NORMAL_MAP = 1,
+ SPECULAR_MAP = 2,
+ NUM_TEXTURE_CHANNELS = 3,
};
enum eVolumeTexIndex
@@ -495,4 +497,24 @@ extern S32 gGLViewport[4];
extern LLRender gGL;
+// 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 };
+
+glh::matrix4f copy_matrix(F32* src);
+glh::matrix4f get_current_modelview();
+glh::matrix4f get_current_projection();
+glh::matrix4f get_last_modelview();
+glh::matrix4f get_last_projection();
+
+void copy_matrix(const glh::matrix4f& src, F32* dst);
+void set_current_modelview(const glh::matrix4f& mat);
+void 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);
#endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index e721ad93fa..3c25d6aaa8 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -35,11 +35,7 @@
#include "OpenGL/OpenGL.h"
#endif
-#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-#else
-#define UNIFORM_ERRS LL_ERRS("Shader")
-#endif
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
@@ -98,7 +94,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
- if (features->calculatesLighting || features->atmosphericHelpers)
+ if (features->calculatesLighting || features->calculatesAtmospherics)
{
if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
{
@@ -194,6 +190,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
+ if (features->calculatesLighting || features->calculatesAtmospherics)
+ {
+ if (!shader->attachObject("windlight/atmosphericsHelpersF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->hasGamma)
{
@@ -202,7 +206,31 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
}
-
+
+ if (features->hasSrgb)
+ {
+ if (!shader->attachObject("environment/srgbF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->encodesNormal)
+ {
+ if (!shader->attachObject("environment/encodeNormF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->decodesNormal)
+ {
+ if (!shader->attachObject("environment/decodeNormF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
if (features->hasAtmospherics)
{
if (!shader->attachObject("windlight/atmosphericsF.glsl"))
@@ -512,21 +540,30 @@ static std::string get_object_log(GLhandleARB ret)
void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename)
{
std::string log = get_object_log(ret);
+ std::string fname = filename;
+ if (filename.empty())
+ {
+ fname = "unknown shader file";
+ }
- if (log.length() > 0 || warns)
+ if (log.length() > 0)
{
- LL_DEBUGS("ShaderLoading") << "Shader loading ";
-
- if (!filename.empty())
- {
- LL_CONT << "From " << filename << ":\n";
- }
- LL_CONT << log << LL_ENDL;
+ LL_WARNS("ShaderLoading") << "Shader loading from " << fname << ":\n" << LL_ENDL;
+ LL_WARNS("ShaderLoading") << log << LL_ENDL;
}
}
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
{
+
+// endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl)
+#if LL_DARWIN
+ if (defines)
+ {
+ (*defines)["OLD_SELECT"] = "1";
+ }
+#endif
+
GLenum error = GL_NO_ERROR;
if (gDebugGL)
{
@@ -1069,6 +1106,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("projection_matrix");
mReservedUniforms.push_back("inv_proj");
mReservedUniforms.push_back("modelview_projection_matrix");
+ mReservedUniforms.push_back("inv_modelview");
mReservedUniforms.push_back("normal_matrix");
mReservedUniforms.push_back("texture_matrix0");
mReservedUniforms.push_back("texture_matrix1");
@@ -1111,13 +1149,16 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("color");
mReservedUniforms.push_back("diffuseMap");
+ mReservedUniforms.push_back("altDiffuseMap");
mReservedUniforms.push_back("specularMap");
mReservedUniforms.push_back("bumpMap");
+ mReservedUniforms.push_back("bumpMap2");
mReservedUniforms.push_back("environmentMap");
- mReservedUniforms.push_back("cloude_noise_texture");
+ mReservedUniforms.push_back("cloud_noise_texture");
+ mReservedUniforms.push_back("cloud_noise_texture_next");
mReservedUniforms.push_back("fullbright");
mReservedUniforms.push_back("lightnorm");
- mReservedUniforms.push_back("sunlight_color_copy");
+ mReservedUniforms.push_back("sunlight_color");
mReservedUniforms.push_back("ambient");
mReservedUniforms.push_back("blue_horizon");
mReservedUniforms.push_back("blue_density");
@@ -1177,6 +1218,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("spot_shadow_bias");
mReservedUniforms.push_back("spot_shadow_offset");
mReservedUniforms.push_back("sun_dir");
+ mReservedUniforms.push_back("moon_dir");
mReservedUniforms.push_back("shadow_res");
mReservedUniforms.push_back("proj_shadow_res");
mReservedUniforms.push_back("depth_cutoff");
@@ -1267,6 +1309,18 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("origin");
mReservedUniforms.push_back("display_gamma");
+
+ mReservedUniforms.push_back("inscatter");
+ mReservedUniforms.push_back("sun_size");
+ mReservedUniforms.push_back("fog_color");
+
+ mReservedUniforms.push_back("transmittance_texture");
+ mReservedUniforms.push_back("scattering_texture");
+ mReservedUniforms.push_back("single_mie_scattering_texture");
+ mReservedUniforms.push_back("irradiance_texture");
+ mReservedUniforms.push_back("blend_factor");
+ mReservedUniforms.push_back("no_atmo");
+
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 394b38f832..7898b2d90a 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -42,6 +42,7 @@ public:
PROJECTION_MATRIX,
INVERSE_PROJECTION_MATRIX,
MODELVIEW_PROJECTION_MATRIX,
+ INVERSE_MODELVIEW_MATRIX,
NORMAL_MATRIX,
TEXTURE_MATRIX0,
TEXTURE_MATRIX1,
@@ -73,10 +74,13 @@ public:
PROJECTOR_AMBIENT_LOD,
DIFFUSE_COLOR,
DIFFUSE_MAP,
+ ALTERNATE_DIFFUSE_MAP,
SPECULAR_MAP,
BUMP_MAP,
+ BUMP_MAP2,
ENVIRONMENT_MAP,
CLOUD_NOISE_MAP,
+ CLOUD_NOISE_MAP_NEXT,
FULLBRIGHT,
LIGHTNORM,
SUNLIGHT_COLOR,
@@ -131,6 +135,7 @@ public:
DEFERRED_SPOT_SHADOW_BIAS,
DEFERRED_SPOT_SHADOW_OFFSET,
DEFERRED_SUN_DIR,
+ DEFERRED_MOON_DIR,
DEFERRED_SHADOW_RES,
DEFERRED_PROJ_SHADOW_RES,
DEFERRED_DEPTH_CUTOFF,
@@ -215,7 +220,20 @@ public:
TERRAIN_ALPHARAMP,
SHINY_ORIGIN,
-DISPLAY_GAMMA,
+ DISPLAY_GAMMA,
+
+ INSCATTER_RT,
+ SUN_SIZE,
+ FOG_COLOR,
+
+ // precomputed textures from libatmosphere
+ TRANSMITTANCE_TEX,
+ SCATTER_TEX,
+ SINGLE_MIE_SCATTER_TEX,
+ ILLUMINANCE_TEX,
+ BLEND_FACTOR,
+
+ NO_ATMO,
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp
index 90fbcec2be..6eef36216c 100644
--- a/indra/llrender/lltexture.cpp
+++ b/indra/llrender/lltexture.cpp
@@ -29,3 +29,15 @@
LLTexture::~LLTexture()
{
}
+
+S8 LLTexture::getType() const { llassert(false); return 0; }
+void LLTexture::setKnownDrawSize(S32 width, S32 height) { llassert(false); }
+bool LLTexture::bindDefaultImage(const S32 stage) { llassert(false); return false; }
+bool LLTexture::bindDebugImage(const S32 stage) { llassert(false); return false; }
+void LLTexture::forceImmediateUpdate() { llassert(false); }
+void LLTexture::setActive() { llassert(false); }
+S32 LLTexture::getWidth(S32 discard_level) const { llassert(false); return 0; }
+S32 LLTexture::getHeight(S32 discard_level) const { llassert(false); return 0; }
+bool LLTexture::isActiveFetching() { llassert(false); return false; }
+LLImageGL* LLTexture::getGLTexture() const { llassert(false); return nullptr; }
+void LLTexture::updateBindStatsForTester() { }
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 9fca8b8cd3..41481fb8a7 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -58,21 +58,21 @@ public:
//
//interfaces to access LLGLTexture
//
- virtual S8 getType() const = 0 ;
- virtual void setKnownDrawSize(S32 width, S32 height) = 0 ;
- virtual bool bindDefaultImage(const S32 stage = 0) = 0 ;
- virtual bool bindDebugImage(const S32 stage = 0) = 0;
- virtual void forceImmediateUpdate() = 0 ;
- virtual void setActive() = 0 ;
- virtual S32 getWidth(S32 discard_level = -1) const = 0 ;
- virtual S32 getHeight(S32 discard_level = -1) const = 0 ;
- virtual bool isActiveFetching() = 0;
+ virtual S8 getType() const;
+ virtual void setKnownDrawSize(S32 width, S32 height);
+ virtual bool bindDefaultImage(const S32 stage = 0);
+ virtual bool bindDebugImage(const S32 stage = 0);
+ virtual void forceImmediateUpdate();
+ virtual void setActive();
+ virtual S32 getWidth(S32 discard_level = -1) const;
+ virtual S32 getHeight(S32 discard_level = -1) const;
+ virtual bool isActiveFetching();
private:
//note: do not make this function public.
- virtual LLImageGL* getGLTexture() const = 0 ;
+ virtual LLImageGL* getGLTexture() const;
- virtual void updateBindStatsForTester() = 0 ;
+ virtual void updateBindStatsForTester();
};
#endif
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 8054eb3619..54e4d296ab 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -133,8 +133,10 @@ set(llui_SOURCE_FILES
llview.cpp
llviewquery.cpp
llviewereventrecorder.cpp
+ llvirtualtrackball.cpp
llwindowshade.cpp
llxuiparser.cpp
+ llxyvector.cpp
)
set(llui_HEADER_FILES
@@ -249,8 +251,10 @@ set(llui_HEADER_FILES
llview.h
llviewereventrecorder.h
llviewquery.h
+ llvirtualtrackball.h
llwindowshade.h
llxuiparser.h
+ llxyvector.h
)
set_source_files_properties(${llui_HEADER_FILES}
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 895753aeae..9d0f4b6db1 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -149,6 +149,7 @@ LLFolderView::Params::Params()
use_label_suffix("use_label_suffix"),
allow_multiselect("allow_multiselect", true),
show_empty_message("show_empty_message", true),
+ suppress_folder_menu("suppress_folder_menu", false),
use_ellipses("use_ellipses", false),
options_menu("options_menu", "")
{
@@ -167,6 +168,7 @@ LLFolderView::LLFolderView(const Params& p)
mRenameItem( NULL ),
mNeedsScroll( FALSE ),
mUseLabelSuffix(p.use_label_suffix),
+ mSuppressFolderMenu(p.suppress_folder_menu),
mPinningSelectedItem(FALSE),
mNeedsAutoSelect( FALSE ),
mAutoSelectOverride(FALSE),
@@ -1432,10 +1434,13 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size();
+
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if ( handled
+ bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected();
+ if ((handled
&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
- && menu )
+ && menu ) &&
+ !hide_folder_menu)
{
if (mCallbackRegistrar)
{
@@ -1449,7 +1454,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
if (mCallbackRegistrar)
{
mCallbackRegistrar->popScope();
- }
+ }
}
else
{
@@ -1862,6 +1867,20 @@ void LLFolderView::updateMenu()
}
}
+bool LLFolderView::isFolderSelected()
+{
+ selected_items_t::iterator item_iter;
+ for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
+ {
+ LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(*item_iter);
+ if (folder != NULL)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
bool LLFolderView::selectFirstItem()
{
for (folders_t::iterator iter = mFolders.begin();
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 2926e160d0..69824992c1 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -92,7 +92,8 @@ public:
allow_multiselect,
show_empty_message,
use_ellipses,
- show_item_link_overlays;
+ show_item_link_overlays,
+ suppress_folder_menu;
Mandatory<LLFolderViewModelInterface*> view_model;
Optional<LLFolderViewGroupedItemModel*> grouped_item_model;
Mandatory<std::string> options_menu;
@@ -259,6 +260,8 @@ protected:
void closeRenamer( void );
+ bool isFolderSelected();
+
bool selectFirstItem();
bool selectLastItem();
@@ -282,7 +285,8 @@ protected:
mDragAndDropThisFrame,
mShowItemLinkOverlays,
mShowSelectionContext,
- mShowSingleSelection;
+ mShowSingleSelection,
+ mSuppressFolderMenu;
// Renaming variables and methods
LLFolderViewItem* mRenameItem; // The item currently being renamed
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index 0aa3e17075..c35b7c5496 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -54,13 +54,18 @@ LLMultiSlider::SliderParams::SliderParams()
LLMultiSlider::Params::Params()
: max_sliders("max_sliders", 1),
allow_overlap("allow_overlap", false),
+ loop_overlap("loop_overlap", false),
+ orientation("orientation"),
+ overlap_threshold("overlap_threshold", 0),
draw_track("draw_track", true),
use_triangle("use_triangle", false),
track_color("track_color"),
thumb_disabled_color("thumb_disabled_color"),
+ thumb_highlight_color("thumb_highlight_color"),
thumb_outline_color("thumb_outline_color"),
thumb_center_color("thumb_center_color"),
thumb_center_selected_color("thumb_center_selected_color"),
+ thumb_image("thumb_image"),
triangle_color("triangle_color"),
mouse_down_callback("mouse_down_callback"),
mouse_up_callback("mouse_up_callback"),
@@ -71,9 +76,9 @@ LLMultiSlider::Params::Params()
LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
: LLF32UICtrl(p),
mMouseOffset( 0 ),
- mDragStartThumbRect( 0, getRect().getHeight(), p.thumb_width, 0 ),
mMaxNumSliders(p.max_sliders),
mAllowOverlap(p.allow_overlap),
+ mLoopOverlap(p.loop_overlap),
mDrawTrack(p.draw_track),
mUseTriangle(p.use_triangle),
mTrackColor(p.track_color()),
@@ -83,12 +88,22 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
mDisabledThumbColor(p.thumb_disabled_color()),
mTriangleColor(p.triangle_color()),
mThumbWidth(p.thumb_width),
+ mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL),
mMouseDownSignal(NULL),
mMouseUpSignal(NULL)
{
mValue.emptyMap();
mCurSlider = LLStringUtil::null;
-
+
+ if (mOrientation == HORIZONTAL)
+ {
+ mDragStartThumbRect = LLRect(0, getRect().getHeight(), p.thumb_width, 0);
+ }
+ else
+ {
+ mDragStartThumbRect = LLRect(0, p.thumb_width, getRect().getWidth(), 0);
+ }
+
if (p.mouse_down_callback.isProvided())
{
setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
@@ -98,6 +113,15 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
+ if (p.overlap_threshold.isProvided())
+ {
+ mOverlapThreshold = p.overlap_threshold;
+ }
+ else
+ {
+ mOverlapThreshold = 0;
+ }
+
for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders.begin();
it != p.sliders.end();
++it)
@@ -111,6 +135,12 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
addSlider(it->value);
}
}
+
+ if (p.thumb_image.isProvided())
+ {
+ mThumbImagep = LLUI::getUIImage(p.thumb_image());
+ }
+ mThumbHighlightColor = p.thumb_highlight_color.isProvided() ? p.thumb_highlight_color() : static_cast<LLUIColor>(gFocusMgr.getFocusColor());
}
LLMultiSlider::~LLMultiSlider()
@@ -143,14 +173,40 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from
// look at the current spot
// and see if anything is there
LLSD::map_iterator mIt = mValue.beginMap();
- for(;mIt != mValue.endMap(); mIt++) {
-
- F32 testVal = (F32)mIt->second.asReal() - newValue;
- if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD &&
- mIt->first != name) {
+
+ // increment is our distance between points, use to eliminate round error
+ F32 threshold = mOverlapThreshold + (mIncrement / 4);
+ // If loop overlap is enabled, check if we overlap with points 'after' max value (project to lower)
+ F32 loop_up_check = (mLoopOverlap && (value + threshold) > mMaxValue) ? (value + threshold - mMaxValue + mMinValue) : mMinValue - 1.0f;
+ // If loop overlap is enabled, check if we overlap with points 'before' min value (project to upper)
+ F32 loop_down_check = (mLoopOverlap && (value - threshold) < mMinValue) ? (value - threshold - mMinValue + mMaxValue) : mMaxValue + 1.0f;
+
+ for(;mIt != mValue.endMap(); mIt++)
+ {
+ F32 locationVal = (F32)mIt->second.asReal();
+ // Check nearby values
+ F32 testVal = locationVal - newValue;
+ if (testVal > -threshold
+ && testVal < threshold
+ && mIt->first != name)
+ {
hit = true;
break;
}
+ if (mLoopOverlap)
+ {
+ // Check edge overlap values
+ if (locationVal < loop_up_check)
+ {
+ hit = true;
+ break;
+ }
+ if (locationVal > loop_down_check)
+ {
+ hit = true;
+ break;
+ }
+ }
}
// if none found, stop
@@ -170,13 +226,26 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from
}
F32 t = (newValue - mMinValue) / (mMaxValue - mMinValue);
+ if (mOrientation == HORIZONTAL)
+ {
+ S32 left_edge = mThumbWidth/2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
- S32 left_edge = mThumbWidth/2;
- S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
+ S32 x = left_edge + S32( t * (right_edge - left_edge) );
- S32 x = left_edge + S32( t * (right_edge - left_edge) );
- mThumbRects[name].mLeft = x - (mThumbWidth/2);
- mThumbRects[name].mRight = x + (mThumbWidth/2);
+ mThumbRects[name].mLeft = x - (mThumbWidth / 2);
+ mThumbRects[name].mRight = x + (mThumbWidth / 2);
+ }
+ else
+ {
+ S32 bottom_edge = mThumbWidth/2;
+ S32 top_edge = getRect().getHeight() - (mThumbWidth/2);
+
+ S32 x = bottom_edge + S32( t * (top_edge - bottom_edge) );
+
+ mThumbRects[name].mTop = x + (mThumbWidth / 2);
+ mThumbRects[name].mBottom = x - (mThumbWidth / 2);
+ }
}
void LLMultiSlider::setValue(const LLSD& value)
@@ -196,7 +265,11 @@ void LLMultiSlider::setValue(const LLSD& value)
F32 LLMultiSlider::getSliderValue(const std::string& name) const
{
- return (F32)mValue[name].asReal();
+ if (mValue.has(name))
+ {
+ return (F32)mValue[name].asReal();
+ }
+ return 0;
}
void LLMultiSlider::setCurSlider(const std::string& name)
@@ -206,6 +279,38 @@ void LLMultiSlider::setCurSlider(const std::string& name)
}
}
+F32 LLMultiSlider::getSliderValueFromPos(S32 xpos, S32 ypos) const
+{
+ F32 t = 0;
+ if (mOrientation == HORIZONTAL)
+ {
+ S32 left_edge = mThumbWidth / 2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth / 2);
+
+ xpos += mMouseOffset;
+ xpos = llclamp(xpos, left_edge, right_edge);
+
+ t = F32(xpos - left_edge) / (right_edge - left_edge);
+ }
+ else
+ {
+ S32 bottom_edge = mThumbWidth / 2;
+ S32 top_edge = getRect().getHeight() - (mThumbWidth / 2);
+
+ ypos += mMouseOffset;
+ ypos = llclamp(ypos, bottom_edge, top_edge);
+
+ t = F32(ypos - bottom_edge) / (top_edge - bottom_edge);
+ }
+
+ return((t * (mMaxValue - mMinValue)) + mMinValue);
+}
+
+void LLMultiSlider::resetCurSlider()
+{
+ mCurSlider = LLStringUtil::null;
+}
+
const std::string& LLMultiSlider::addSlider()
{
return addSlider(mInitialValue);
@@ -230,7 +335,14 @@ const std::string& LLMultiSlider::addSlider(F32 val)
}
// add a new thumb rect
- mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 );
+ if (mOrientation == HORIZONTAL)
+ {
+ mThumbRects[newName.str()] = LLRect(0, getRect().getHeight(), mThumbWidth, 0);
+ }
+ else
+ {
+ mThumbRects[newName.str()] = LLRect(0, mThumbWidth, getRect().getWidth(), 0);
+ }
// add the value and set the current slider to this one
mValue.insert(newName.str(), initVal);
@@ -256,7 +368,14 @@ void LLMultiSlider::addSlider(F32 val, const std::string& name)
}
// add a new thumb rect
- mThumbRects[name] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 );
+ if (mOrientation == HORIZONTAL)
+ {
+ mThumbRects[name] = LLRect(0, getRect().getHeight(), mThumbWidth, 0);
+ }
+ else
+ {
+ mThumbRects[name] = LLRect(0, mThumbWidth, getRect().getWidth(), 0);
+ }
// add the value and set the current slider to this one
mValue.insert(name, initVal);
@@ -278,11 +397,13 @@ bool LLMultiSlider::findUnusedValue(F32& initVal)
// look at the current spot
// and see if anything is there
+ F32 threshold = mAllowOverlap ? FLOAT_THRESHOLD : mOverlapThreshold + (mIncrement / 4);
LLSD::map_iterator mIt = mValue.beginMap();
for(;mIt != mValue.endMap(); mIt++) {
F32 testVal = (F32)mIt->second.asReal() - initVal;
- if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD) {
+ if(testVal > -threshold && testVal < threshold)
+ {
hit = true;
break;
}
@@ -334,10 +455,15 @@ void LLMultiSlider::deleteSlider(const std::string& name)
void LLMultiSlider::clear()
{
- while(mThumbRects.size() > 0) {
+ while(mThumbRects.size() > 0 && mValue.size() > 0) {
deleteCurSlider();
}
+ if (mThumbRects.size() > 0 || mValue.size() > 0)
+ {
+ LL_WARNS() << "Failed to fully clear Multi slider" << LL_ENDL;
+ }
+
LLF32UICtrl::clear();
}
@@ -345,14 +471,15 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask)
{
if( gFocusMgr.getMouseCapture() == this )
{
- S32 left_edge = mThumbWidth/2;
- S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
-
- x += mMouseOffset;
- x = llclamp( x, left_edge, right_edge );
-
- F32 t = F32(x - left_edge) / (right_edge - left_edge);
- setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue );
+// S32 left_edge = mThumbWidth/2;
+// S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
+//
+// x += mMouseOffset;
+// x = llclamp( x, left_edge, right_edge );
+//
+// F32 t = F32(x - left_edge) / (right_edge - left_edge);
+// setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue );
+ setCurSliderValue(getSliderValueFromPos(x, y));
onCommit();
getWindow()->setCursor(UI_CURSOR_ARROW);
@@ -416,20 +543,30 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
}
}
- // Find the offset of the actual mouse location from the center of the thumb.
- if (mThumbRects[mCurSlider].pointInRect(x,y))
- {
- mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x;
- }
- else
+ if (!mCurSlider.empty())
{
- mMouseOffset = 0;
- }
+ // Find the offset of the actual mouse location from the center of the thumb.
+ if (mThumbRects[mCurSlider].pointInRect(x,y))
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth / 2) - x;
+ }
+ else
+ {
+ mMouseOffset = (mThumbRects[mCurSlider].mBottom + mThumbWidth / 2) - y;
+ }
+ }
+ else
+ {
+ mMouseOffset = 0;
+ }
- // Start dragging the thumb
- // No handler needed for focus lost since this class has no state that depends on it.
- gFocusMgr.setMouseCapture( this );
- mDragStartThumbRect = mThumbRects[mCurSlider];
+ // Start dragging the thumb
+ // No handler needed for focus lost since this class has no state that depends on it.
+ gFocusMgr.setMouseCapture( this );
+ mDragStartThumbRect = mThumbRects[mCurSlider];
+ }
}
make_ui_sound("UISndClick");
@@ -483,9 +620,18 @@ void LLMultiSlider::draw()
// Track
LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square");
- static LLUICachedControl<S32> multi_track_height ("UIMultiTrackHeight", 0);
- S32 height_offset = (getRect().getHeight() - multi_track_height) / 2;
- LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset );
+ static LLUICachedControl<S32> multi_track_height_width ("UIMultiTrackHeight", 0);
+ S32 height_offset = 0;
+ S32 width_offset = 0;
+ if (mOrientation == HORIZONTAL)
+ {
+ height_offset = (getRect().getHeight() - multi_track_height_width) / 2;
+ }
+ else
+ {
+ width_offset = (getRect().getWidth() - multi_track_height_width) / 2;
+ }
+ LLRect track_rect(width_offset, getRect().getHeight() - height_offset, getRect().getWidth() - width_offset, height_offset);
if(mDrawTrack)
@@ -510,7 +656,7 @@ void LLMultiSlider::draw()
mTriangleColor.get() % opacity, TRUE);
}
}
- else if (!thumb_imagep)
+ else if (!thumb_imagep && !mThumbImagep)
{
// draw all the thumbs
curSldrIt = mThumbRects.end();
@@ -540,15 +686,33 @@ void LLMultiSlider::draw()
gl_rect_2d(mDragStartThumbRect, mThumbCenterColor.get() % opacity, FALSE);
}
}
- else if( gFocusMgr.getMouseCapture() == this )
+ else
{
- // draw drag start
- thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
+ LLMouseHandler* capture = gFocusMgr.getMouseCapture();
+ if (capture == this)
+ {
+ // draw drag start (ghost)
+ if (mThumbImagep)
+ {
+ mThumbImagep->draw(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
+ }
+ else
+ {
+ thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
+ }
+ }
// draw the highlight
- if (hasFocus())
+ if (hasFocus() && !mCurSlider.empty())
{
- thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
+ if (mThumbImagep)
+ {
+ mThumbImagep->drawBorder(mThumbRects[mCurSlider], mThumbHighlightColor, gFocusMgr.getFocusFlashWidth());
+ }
+ else
+ {
+ thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
+ }
}
// draw the thumbs
@@ -565,44 +729,35 @@ void LLMultiSlider::draw()
}
// the draw command
- thumb_imagep->drawSolid(mIt->second, curThumbColor);
+ if (mThumbImagep)
+ {
+ mThumbImagep->draw(mIt->second);
+ }
+ else if (capture == this)
+ {
+ thumb_imagep->drawSolid(mIt->second, curThumbColor);
+ }
+ else
+ {
+ thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity);
+ }
}
// draw cur slider last
if(curSldrIt != mThumbRects.end())
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
- }
-
- }
- else
- {
- // draw highlight
- if (hasFocus())
- {
- thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
- }
-
- // draw thumbs
- curSldrIt = mThumbRects.end();
- for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++)
- {
-
- // choose the color
- curThumbColor = mThumbCenterColor.get();
- if(mIt->first == mCurSlider)
+ if (mThumbImagep)
{
- curSldrIt = mIt;
- continue;
- //curThumbColor = mThumbCenterSelectedColor;
- }
-
- thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity);
- }
-
- if(curSldrIt != mThumbRects.end())
- {
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
+ mThumbImagep->draw(curSldrIt->second);
+ }
+ else if (capture == this)
+ {
+ thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
+ }
+ else
+ {
+ thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
+ }
}
}
diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h
index 2b422e89c9..52c6d1ddef 100644
--- a/indra/llui/llmultislider.h
+++ b/indra/llui/llmultislider.h
@@ -47,16 +47,23 @@ public:
Optional<S32> max_sliders;
Optional<bool> allow_overlap,
+ loop_overlap,
draw_track,
use_triangle;
+ Optional<F32> overlap_threshold;
+
Optional<LLUIColor> track_color,
thumb_disabled_color,
+ thumb_highlight_color,
thumb_outline_color,
thumb_center_color,
thumb_center_selected_color,
triangle_color;
+ Optional<std::string> orientation,
+ thumb_image;
+
Optional<CommitCallbackParam> mouse_down_callback,
mouse_up_callback;
Optional<S32> thumb_width;
@@ -72,10 +79,12 @@ public:
virtual ~LLMultiSlider();
void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE);
F32 getSliderValue(const std::string& name) const;
+ F32 getSliderValueFromPos(S32 xpos, S32 ypos) const;
const std::string& getCurSlider() const { return mCurSlider; }
F32 getCurSliderValue() const { return getSliderValue(mCurSlider); }
void setCurSlider(const std::string& name);
+ void resetCurSlider();
void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mCurSlider, val, from_event); }
/*virtual*/ void setValue(const LLSD& value);
@@ -98,6 +107,10 @@ public:
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ void draw();
+ S32 getMaxNumSliders() { return mMaxNumSliders; }
+ S32 getCurNumSliders() { return mValue.size(); }
+ bool canAddSliders() { return mValue.size() < mMaxNumSliders; }
+
protected:
LLSD mValue;
std::string mCurSlider;
@@ -105,6 +118,8 @@ protected:
S32 mMaxNumSliders;
BOOL mAllowOverlap;
+ BOOL mLoopOverlap;
+ F32 mOverlapThreshold;
BOOL mDrawTrack;
BOOL mUseTriangle; /// hacked in toggle to use a triangle
@@ -116,11 +131,15 @@ protected:
mThumbRects;
LLUIColor mTrackColor;
LLUIColor mThumbOutlineColor;
+ LLUIColor mThumbHighlightColor;
LLUIColor mThumbCenterColor;
LLUIColor mThumbCenterSelectedColor;
LLUIColor mDisabledThumbColor;
LLUIColor mTriangleColor;
-
+ LLUIImagePtr mThumbImagep; //blimps on the slider, for now no 'disabled' support
+
+ const EOrientation mOrientation;
+
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
};
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index c460a08afc..972567ef9b 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -53,6 +53,12 @@ LLMultiSliderCtrl::Params::Params()
can_edit_text("can_edit_text", false),
max_sliders("max_sliders", 1),
allow_overlap("allow_overlap", false),
+ loop_overlap("loop_overlap", false),
+ orientation("orientation"),
+ thumb_image("thumb_image"),
+ thumb_width("thumb_width"),
+ thumb_highlight_color("thumb_highlight_color"),
+ overlap_threshold("overlap_threshold", 0),
draw_track("draw_track", true),
use_triangle("use_triangle", false),
decimal_digits("decimal_digits", 3),
@@ -167,6 +173,19 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
params.increment(p.increment);
params.max_sliders(p.max_sliders);
params.allow_overlap(p.allow_overlap);
+ params.loop_overlap(p.loop_overlap);
+ if (p.overlap_threshold.isProvided())
+ {
+ params.overlap_threshold = p.overlap_threshold;
+ }
+ params.orientation(p.orientation);
+ params.thumb_image(p.thumb_image);
+ params.thumb_highlight_color(p.thumb_highlight_color);
+ if (p.thumb_width.isProvided())
+ {
+ // otherwise should be provided by template
+ params.thumb_width(p.thumb_width);
+ }
params.draw_track(p.draw_track);
params.use_triangle(p.use_triangle);
params.control_name(p.control_name);
@@ -213,6 +232,11 @@ void LLMultiSliderCtrl::setCurSlider(const std::string& name)
mCurValue = mMultiSlider->getCurSliderValue();
}
+void LLMultiSliderCtrl::resetCurSlider()
+{
+ mMultiSlider->resetCurSlider();
+}
+
BOOL LLMultiSliderCtrl::setLabelArg( const std::string& key, const LLStringExplicit& text )
{
BOOL res = FALSE;
diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h
index b6a3542376..c370ebf505 100644
--- a/indra/llui/llmultisliderctrl.h
+++ b/indra/llui/llmultisliderctrl.h
@@ -51,14 +51,22 @@ public:
text_width;
Optional<bool> show_text,
can_edit_text;
- Optional<S32> decimal_digits;
+ Optional<S32> decimal_digits,
+ thumb_width;
Optional<S32> max_sliders;
Optional<bool> allow_overlap,
+ loop_overlap,
draw_track,
use_triangle;
+ Optional<std::string> orientation,
+ thumb_image;
+
+ Optional<F32> overlap_threshold;
+
Optional<LLUIColor> text_color,
- text_disabled_color;
+ text_disabled_color,
+ thumb_highlight_color;
Optional<CommitCallbackParam> mouse_down_callback,
mouse_up_callback;
@@ -74,7 +82,7 @@ protected:
public:
virtual ~LLMultiSliderCtrl();
- F32 getSliderValue(const std::string& name) const;
+ F32 getSliderValue(const std::string& name) const { return mMultiSlider->getSliderValue(name); }
void setSliderValue(const std::string& name, F32 v, BOOL from_event = FALSE);
virtual void setValue(const LLSD& value );
@@ -84,6 +92,7 @@ public:
const std::string& getCurSlider() const { return mMultiSlider->getCurSlider(); }
F32 getCurSliderValue() const { return mCurValue; }
void setCurSlider(const std::string& name);
+ void resetCurSlider();
void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); }
virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); }
@@ -98,6 +107,8 @@ public:
void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);}
void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);}
+ F32 getSliderValueFromPos(S32 x, S32 y) const { return mMultiSlider->getSliderValueFromPos(x, y); }
+
/// for adding and deleting sliders
const std::string& addSlider();
const std::string& addSlider(F32 val);
@@ -107,6 +118,10 @@ public:
F32 getMinValue() const { return mMultiSlider->getMinValue(); }
F32 getMaxValue() const { return mMultiSlider->getMaxValue(); }
+ S32 getMaxNumSliders() { return mMultiSlider->getMaxNumSliders(); }
+ S32 getCurNumSliders() { return mMultiSlider->getCurNumSliders(); }
+ bool canAddSliders() { return mMultiSlider->canAddSliders(); }
+
void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); }
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; }
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; }
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index ebbb951ee6..6925c0a130 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -331,8 +331,9 @@ void LLSlider::draw()
highlight_rect.set(track_rect.mLeft, track_rect.mTop, track_rect.mRight, track_rect.mBottom);
}
- trackImage->draw(track_rect, LLColor4::white % alpha);
- trackHighlightImage->draw(highlight_rect, LLColor4::white % alpha);
+ LLColor4 color = isInEnabledChain() ? LLColor4::white % alpha : LLColor4::white % (0.6f * alpha);
+ trackImage->draw(track_rect, color);
+ trackHighlightImage->draw(highlight_rect, color);
// Thumb
if (hasFocus())
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index d7151dbee9..59fc1ddcef 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -33,7 +33,6 @@
#include "llcontrol.h"
#include "llcoord.h"
#include "llcontrol.h"
-#include "llglslshader.h"
#include "llinitparam.h"
#include "llregistry.h"
#include "llrender2dutils.h"
@@ -49,7 +48,6 @@
// for initparam specialization
#include "llfontgl.h"
-
class LLUUID;
class LLWindow;
class LLView;
@@ -77,7 +75,8 @@ enum EDragAndDropType
DAD_MESH = 15,
DAD_WIDGET = 16,
DAD_PERSON = 17,
- DAD_COUNT = 18, // number of types in this enum
+ DAD_SETTINGS = 18,
+ DAD_COUNT = 19, // number of types in this enum
};
// Reasons for drags to be denied.
diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp
new file mode 100644
index 0000000000..723643dd25
--- /dev/null
+++ b/indra/llui/llvirtualtrackball.cpp
@@ -0,0 +1,480 @@
+/**
+* @file LLVirtualTrackball.cpp
+* @author Andrey Lihatskiy
+* @brief Implementation for LLVirtualTrackball
+*
+* $LicenseInfo:firstyear=2001&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$
+*/
+
+// A control for positioning the sun and the moon in the celestial sphere.
+
+#include "linden_common.h"
+#include "llvirtualtrackball.h"
+#include "llstring.h"
+#include "llrect.h"
+#include "lluictrlfactory.h"
+#include "llrender.h"
+
+// Globals
+static LLDefaultChildRegistry::Register<LLVirtualTrackball> register_virtual_trackball("sun_moon_trackball");
+
+const LLVector3 VectorZero(1.0f, 0.0f, 0.0f);
+
+LLVirtualTrackball::Params::Params()
+ : border("border"),
+ image_moon_back("image_moon_back"),
+ image_moon_front("image_moon_front"),
+ image_sphere("image_sphere"),
+ image_sun_back("image_sun_back"),
+ image_sun_front("image_sun_front"),
+ btn_rotate_top("button_rotate_top"),
+ btn_rotate_bottom("button_rotate_bottom"),
+ btn_rotate_left("button_rotate_left"),
+ btn_rotate_right("button_rotate_right"),
+ thumb_mode("thumb_mode"),
+ lbl_N("labelN"),
+ lbl_S("labelS"),
+ lbl_W("labelW"),
+ lbl_E("labelE"),
+ increment_angle_mouse("increment_angle_mouse", 0.5f),
+ increment_angle_btn("increment_angle_btn", 3.0f)
+{
+}
+
+LLVirtualTrackball::LLVirtualTrackball(const LLVirtualTrackball::Params& p)
+ : LLUICtrl(p),
+ mImgMoonBack(p.image_moon_back),
+ mImgMoonFront(p.image_moon_front),
+ mImgSunBack(p.image_sun_back),
+ mImgSunFront(p.image_sun_front),
+ mImgSphere(p.image_sphere),
+ mThumbMode(p.thumb_mode() == "moon" ? ThumbMode::MOON : ThumbMode::SUN),
+ mIncrementMouse(DEG_TO_RAD * p.increment_angle_mouse()),
+ mIncrementBtn(DEG_TO_RAD * p.increment_angle_btn())
+{
+ LLRect border_rect = getLocalRect();
+ S32 centerX = border_rect.getCenterX();
+ S32 centerY = border_rect.getCenterY();
+ U32 btn_size = 32; // width & height
+ U32 axis_offset_lt = 16; // offset from the axis for left/top sides
+ U32 axis_offset_rb = btn_size - axis_offset_lt; // and for right/bottom
+
+ LLViewBorder::Params border = p.border;
+ border.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder>(border);
+ addChild(mBorder);
+
+
+ LLButton::Params btn_rt = p.btn_rotate_top;
+ btn_rt.rect(LLRect(centerX - axis_offset_lt, border_rect.mTop, centerX + axis_offset_rb, border_rect.mTop - btn_size));
+ btn_rt.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopClick, this));
+ btn_rt.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopClick, this));
+ btn_rt.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopMouseEnter, this));
+ mBtnRotateTop = LLUICtrlFactory::create<LLButton>(btn_rt);
+ addChild(mBtnRotateTop);
+
+ LLTextBox::Params lbl_N = p.lbl_N;
+ LLRect rect_N = btn_rt.rect;
+ //rect_N.translate(btn_rt.rect().getWidth(), 0);
+ lbl_N.rect = rect_N;
+ lbl_N.initial_value(lbl_N.label());
+ mLabelN = LLUICtrlFactory::create<LLTextBox>(lbl_N);
+ addChild(mLabelN);
+
+
+ LLButton::Params btn_rr = p.btn_rotate_right;
+ btn_rr.rect(LLRect(border_rect.mRight - btn_size, centerY + axis_offset_lt, border_rect.mRight, centerY - axis_offset_rb));
+ btn_rr.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightClick, this));
+ btn_rr.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightClick, this));
+ btn_rr.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightMouseEnter, this));
+ mBtnRotateRight = LLUICtrlFactory::create<LLButton>(btn_rr);
+ addChild(mBtnRotateRight);
+
+ LLTextBox::Params lbl_E = p.lbl_E;
+ LLRect rect_E = btn_rr.rect;
+ //rect_E.translate(0, -1 * btn_rr.rect().getHeight());
+ lbl_E.rect = rect_E;
+ lbl_E.initial_value(lbl_E.label());
+ mLabelE = LLUICtrlFactory::create<LLTextBox>(lbl_E);
+ addChild(mLabelE);
+
+
+ LLButton::Params btn_rb = p.btn_rotate_bottom;
+ btn_rb.rect(LLRect(centerX - axis_offset_lt, border_rect.mBottom + btn_size, centerX + axis_offset_rb, border_rect.mBottom));
+ btn_rb.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomClick, this));
+ btn_rb.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomClick, this));
+ btn_rb.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomMouseEnter, this));
+ mBtnRotateBottom = LLUICtrlFactory::create<LLButton>(btn_rb);
+ addChild(mBtnRotateBottom);
+
+ LLTextBox::Params lbl_S = p.lbl_S;
+ LLRect rect_S = btn_rb.rect;
+ //rect_S.translate(btn_rb.rect().getWidth(), 0);
+ lbl_S.rect = rect_S;
+ lbl_S.initial_value(lbl_S.label());
+ mLabelS = LLUICtrlFactory::create<LLTextBox>(lbl_S);
+ addChild(mLabelS);
+
+
+ LLButton::Params btn_rl = p.btn_rotate_left;
+ btn_rl.rect(LLRect(border_rect.mLeft, centerY + axis_offset_lt, border_rect.mLeft + btn_size, centerY - axis_offset_rb));
+ btn_rl.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftClick, this));
+ btn_rl.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftClick, this));
+ btn_rl.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftMouseEnter, this));
+ mBtnRotateLeft = LLUICtrlFactory::create<LLButton>(btn_rl);
+ addChild(mBtnRotateLeft);
+
+ LLTextBox::Params lbl_W = p.lbl_W;
+ LLRect rect_W = btn_rl.rect;
+ //rect_W.translate(0, -1* btn_rl.rect().getHeight());
+ lbl_W.rect = rect_W;
+ lbl_W.initial_value(lbl_W.label());
+ mLabelW = LLUICtrlFactory::create<LLTextBox>(lbl_W);
+ addChild(mLabelW);
+
+
+ LLPanel::Params touch_area;
+ touch_area.rect = LLRect(centerX - mImgSphere->getWidth() / 2,
+ centerY + mImgSphere->getHeight() / 2,
+ centerX + mImgSphere->getWidth() / 2,
+ centerY - mImgSphere->getHeight() / 2);
+ mTouchArea = LLUICtrlFactory::create<LLPanel>(touch_area);
+ addChild(mTouchArea);
+}
+
+LLVirtualTrackball::~LLVirtualTrackball()
+{
+}
+
+BOOL LLVirtualTrackball::postBuild()
+{
+ return TRUE;
+}
+
+
+void LLVirtualTrackball::drawThumb(S32 x, S32 y, ThumbMode mode, bool upperHemi)
+{
+ LLUIImage* thumb;
+ if (mode == ThumbMode::SUN)
+ {
+ if (upperHemi)
+ {
+ thumb = mImgSunFront;
+ }
+ else
+ {
+ thumb = mImgSunBack;
+ }
+ }
+ else
+ {
+ if (upperHemi)
+ {
+ thumb = mImgMoonFront;
+ }
+ else
+ {
+ thumb = mImgMoonBack;
+ }
+ }
+ thumb->draw(LLRect(x - thumb->getWidth() / 2,
+ y + thumb->getHeight() / 2,
+ x + thumb->getWidth() / 2,
+ y - thumb->getHeight() / 2));
+}
+
+bool LLVirtualTrackball::pointInTouchCircle(S32 x, S32 y) const
+{
+ S32 centerX = mTouchArea->getRect().getCenterX();
+ S32 centerY = mTouchArea->getRect().getCenterY();
+
+ bool in_circle = pow(x - centerX, 2) + pow(y - centerY, 2) <= pow(mTouchArea->getRect().getWidth() / 2, 2);
+ return in_circle;
+}
+
+void LLVirtualTrackball::draw()
+{
+ LLVector3 draw_point = VectorZero * mValue;
+
+ S32 halfwidth = mTouchArea->getRect().getWidth() / 2;
+ S32 halfheight = mTouchArea->getRect().getHeight() / 2;
+ draw_point.mV[VX] = (draw_point.mV[VX] + 1.0) * halfwidth + mTouchArea->getRect().mLeft;
+ draw_point.mV[VY] = (draw_point.mV[VY] + 1.0) * halfheight + mTouchArea->getRect().mBottom;
+ bool upper_hemisphere = (draw_point.mV[VZ] >= 0.f);
+
+ mImgSphere->draw(mTouchArea->getRect(), upper_hemisphere ? UI_VERTEX_COLOR : UI_VERTEX_COLOR % 0.5f);
+ drawThumb(draw_point.mV[VX], draw_point.mV[VY], mThumbMode, upper_hemisphere);
+
+
+ if (LLView::sDebugRects)
+ {
+ gGL.color4fv(LLColor4::red.mV);
+ gl_circle_2d(mTouchArea->getRect().getCenterX(), mTouchArea->getRect().getCenterY(), mImgSphere->getWidth() / 2, 60, false);
+ gl_circle_2d(draw_point.mV[VX], draw_point.mV[VY], mImgSunFront->getWidth() / 2, 12, false);
+ }
+
+ // hide the direction labels when disabled
+ BOOL enabled = isInEnabledChain();
+ mLabelN->setVisible(enabled);
+ mLabelE->setVisible(enabled);
+ mLabelS->setVisible(enabled);
+ mLabelW->setVisible(enabled);
+
+ LLView::draw();
+}
+
+void LLVirtualTrackball::onRotateTopClick()
+{
+ if (getEnabled())
+ {
+ LLQuaternion delta;
+ delta.setAngleAxis(mIncrementBtn, 1, 0, 0);
+ mValue *= delta;
+ setValueAndCommit(mValue);
+
+ make_ui_sound("UISndClick");
+ }
+}
+
+void LLVirtualTrackball::onRotateBottomClick()
+{
+ if (getEnabled())
+ {
+ LLQuaternion delta;
+ delta.setAngleAxis(mIncrementBtn, -1, 0, 0);
+ mValue *= delta;
+ setValueAndCommit(mValue);
+
+ make_ui_sound("UISndClick");
+ }
+}
+
+void LLVirtualTrackball::onRotateLeftClick()
+{
+ if (getEnabled())
+ {
+ LLQuaternion delta;
+ delta.setAngleAxis(mIncrementBtn, 0, 1, 0);
+ mValue *= delta;
+ setValueAndCommit(mValue);
+
+ make_ui_sound("UISndClick");
+ }
+}
+
+void LLVirtualTrackball::onRotateRightClick()
+{
+ if (getEnabled())
+ {
+ LLQuaternion delta;
+ delta.setAngleAxis(mIncrementBtn, 0, -1, 0);
+ mValue *= delta;
+ setValueAndCommit(mValue);
+
+ make_ui_sound("UISndClick");
+ }
+}
+
+void LLVirtualTrackball::onRotateTopMouseEnter()
+{
+ mBtnRotateTop->setHighlight(true);
+}
+
+void LLVirtualTrackball::onRotateBottomMouseEnter()
+{
+ mBtnRotateBottom->setHighlight(true);
+}
+
+void LLVirtualTrackball::onRotateLeftMouseEnter()
+{
+ mBtnRotateLeft->setHighlight(true);
+}
+
+void LLVirtualTrackball::onRotateRightMouseEnter()
+{
+ mBtnRotateRight->setHighlight(true);
+}
+
+void LLVirtualTrackball::setValue(const LLSD& value)
+{
+ if (value.isArray() && value.size() == 4)
+ {
+ mValue.setValue(value);
+ }
+}
+
+void LLVirtualTrackball::setRotation(const LLQuaternion &value)
+{
+ mValue = value;
+}
+
+void LLVirtualTrackball::setValue(F32 x, F32 y, F32 z, F32 w)
+{
+ mValue.set(x, y, z, w);
+}
+
+void LLVirtualTrackball::setValueAndCommit(const LLQuaternion &value)
+{
+ mValue = value;
+ onCommit();
+}
+
+LLSD LLVirtualTrackball::getValue() const
+{
+ return mValue.getValue();
+}
+
+LLQuaternion LLVirtualTrackball::getRotation() const
+{
+ return mValue;
+}
+
+BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (hasMouseCapture())
+ {
+ if (mDragMode == DRAG_SCROLL)
+ { // trackball (move to roll) mode
+ LLQuaternion delta;
+
+ F32 rotX = x - mPrevX;
+ F32 rotY = y - mPrevY;
+
+ if (abs(rotX) > 1)
+ {
+ F32 direction = (rotX < 0) ? -1 : 1;
+ delta.setAngleAxis(mIncrementMouse * abs(rotX), 0, direction, 0); // changing X - rotate around Y axis
+ mValue *= delta;
+ }
+
+ if (abs(rotY) > 1)
+ {
+ F32 direction = (rotY < 0) ? 1 : -1; // reverse for Y (value increases from bottom to top)
+ delta.setAngleAxis(mIncrementMouse * abs(rotY), direction, 0, 0); // changing Y - rotate around X axis
+ mValue *= delta;
+ }
+ }
+ else
+ { // set on click mode
+ if (!pointInTouchCircle(x, y))
+ {
+ return TRUE; // don't drag outside the circle
+ }
+
+ F32 radius = mTouchArea->getRect().getWidth() / 2;
+ F32 xx = x - mTouchArea->getRect().getCenterX();
+ F32 yy = y - mTouchArea->getRect().getCenterY();
+ F32 dist = sqrt(pow(xx, 2) + pow(yy, 2));
+
+ F32 azimuth = llclamp(acosf(xx / dist), 0.0f, F_PI);
+ F32 altitude = llclamp(acosf(dist / radius), 0.0f, F_PI_BY_TWO);
+
+ if (yy < 0)
+ {
+ azimuth = F_TWO_PI - azimuth;
+ }
+
+ LLVector3 draw_point = VectorZero * mValue;
+ if (draw_point.mV[VZ] >= 0.f)
+ {
+ if (is_approx_zero(altitude)) // don't change the hemisphere
+ {
+ altitude = F_APPROXIMATELY_ZERO;
+ }
+ altitude *= -1;
+ }
+
+ mValue.setAngleAxis(altitude, 0, 1, 0);
+ LLQuaternion az_quat;
+ az_quat.setAngleAxis(azimuth, 0, 0, 1);
+ mValue *= az_quat;
+ }
+
+ mPrevX = x;
+ mPrevY = y;
+ onCommit();
+ }
+ return TRUE;
+}
+
+BOOL LLVirtualTrackball::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ if (hasMouseCapture())
+ {
+ mPrevX = 0;
+ mPrevY = 0;
+ gFocusMgr.setMouseCapture(NULL);
+ make_ui_sound("UISndClickRelease");
+ }
+ return LLView::handleMouseUp(x, y, mask);
+}
+
+BOOL LLVirtualTrackball::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (pointInTouchCircle(x, y))
+ {
+ mPrevX = x;
+ mPrevY = y;
+ gFocusMgr.setMouseCapture(this);
+ mDragMode = (mask == MASK_CONTROL) ? DRAG_SCROLL : DRAG_SET;
+ make_ui_sound("UISndClick");
+ }
+ return LLView::handleMouseDown(x, y, mask);
+}
+
+BOOL LLVirtualTrackball::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (pointInTouchCircle(x, y))
+ {
+
+ //make_ui_sound("UISndClick");
+ }
+ return LLView::handleRightMouseDown(x, y, mask);
+}
+
+BOOL LLVirtualTrackball::handleKeyHere(KEY key, MASK mask)
+{
+ BOOL handled = FALSE;
+ switch (key)
+ {
+ case KEY_DOWN:
+ onRotateTopClick();
+ handled = TRUE;
+ break;
+ case KEY_LEFT:
+ onRotateRightClick();
+ handled = TRUE;
+ break;
+ case KEY_UP:
+ onRotateBottomClick();
+ handled = TRUE;
+ break;
+ case KEY_RIGHT:
+ onRotateLeftClick();
+ handled = TRUE;
+ break;
+ default:
+ break;
+ }
+ return handled;
+}
+
diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h
new file mode 100644
index 0000000000..2d4b1ece17
--- /dev/null
+++ b/indra/llui/llvirtualtrackball.h
@@ -0,0 +1,160 @@
+/**
+* @file virtualtrackball.h
+* @author Andrey Lihatskiy
+* @brief Header file for LLVirtualTrackball
+*
+* $LicenseInfo:firstyear=2001&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$
+*/
+
+// A control for positioning the sun and the moon in the celestial sphere.
+
+#ifndef LL_LLVIRTUALTRACKBALL_H
+#define LL_LLVIRTUALTRACKBALL_H
+
+#include "lluictrl.h"
+#include "llpanel.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+
+class LLVirtualTrackball
+ : public LLUICtrl
+{
+public:
+ enum ThumbMode
+ {
+ SUN,
+ MOON
+ };
+ enum DragMode
+ {
+ DRAG_SET,
+ DRAG_SCROLL
+ };
+
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLViewBorder::Params> border;
+ Optional<LLUIImage*> image_moon_back,
+ image_moon_front,
+ image_sphere,
+ image_sun_back,
+ image_sun_front;
+
+ Optional<std::string> thumb_mode;
+ Optional<F32> increment_angle_mouse,
+ increment_angle_btn;
+
+ Optional<LLTextBox::Params> lbl_N,
+ lbl_S,
+ lbl_W,
+ lbl_E;
+
+ Optional<LLButton::Params> btn_rotate_top,
+ btn_rotate_bottom,
+ btn_rotate_left,
+ btn_rotate_right;
+
+ Params();
+ };
+
+
+ virtual ~LLVirtualTrackball();
+ /*virtual*/ BOOL postBuild();
+
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseUp(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 handleKeyHere(KEY key, MASK mask);
+
+ virtual void draw();
+
+ virtual void setValue(const LLSD& value);
+ void setValue(F32 x, F32 y, F32 z, F32 w);
+ virtual LLSD getValue() const;
+
+ void setRotation(const LLQuaternion &value);
+ LLQuaternion getRotation() const;
+
+protected:
+ friend class LLUICtrlFactory;
+ LLVirtualTrackball(const Params&);
+ void onEditChange();
+
+protected:
+ LLTextBox* mNLabel;
+ LLTextBox* mELabel;
+ LLTextBox* mSLabel;
+ LLTextBox* mWLabel;
+
+ LLButton* mBtnRotateTop;
+ LLButton* mBtnRotateBottom;
+ LLButton* mBtnRotateLeft;
+ LLButton* mBtnRotateRight;
+
+ LLTextBox* mLabelN;
+ LLTextBox* mLabelS;
+ LLTextBox* mLabelW;
+ LLTextBox* mLabelE;
+
+ LLPanel* mTouchArea;
+ LLViewBorder* mBorder;
+
+private:
+ void setValueAndCommit(const LLQuaternion &value);
+ void drawThumb(S32 x, S32 y, ThumbMode mode, bool upperHemi = true);
+ bool pointInTouchCircle(S32 x, S32 y) const;
+
+ void onRotateTopClick();
+ void onRotateBottomClick();
+ void onRotateLeftClick();
+ void onRotateRightClick();
+
+ void onRotateTopMouseEnter();
+ void onRotateBottomMouseEnter();
+ void onRotateLeftMouseEnter();
+ void onRotateRightMouseEnter();
+
+ S32 mPrevX;
+ S32 mPrevY;
+
+ LLUIImage* mImgMoonBack;
+ LLUIImage* mImgMoonFront;
+ LLUIImage* mImgSunBack;
+ LLUIImage* mImgSunFront;
+ LLUIImage* mImgBtnRotTop;
+ LLUIImage* mImgBtnRotLeft;
+ LLUIImage* mImgBtnRotRight;
+ LLUIImage* mImgBtnRotBottom;
+ LLUIImage* mImgSphere;
+
+ LLQuaternion mValue;
+ ThumbMode mThumbMode;
+ DragMode mDragMode;
+
+ F32 mIncrementMouse;
+ F32 mIncrementBtn;
+};
+
+#endif
+
diff --git a/indra/llui/llxyvector.cpp b/indra/llui/llxyvector.cpp
new file mode 100644
index 0000000000..48f38b8a92
--- /dev/null
+++ b/indra/llui/llxyvector.cpp
@@ -0,0 +1,306 @@
+/**
+* @file llxyvector.cpp
+* @author Andrey Lihatskiy
+* @brief Implementation for LLXYVector
+*
+* $LicenseInfo:firstyear=2001&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$
+*/
+
+// A control that allows to set two related vector magnitudes by manipulating a single vector on a plane.
+
+#include "linden_common.h"
+
+#include "llxyvector.h"
+
+#include "llstring.h"
+#include "llrect.h"
+
+#include "lluictrlfactory.h"
+#include "llrender.h"
+
+// Globals
+static LLDefaultChildRegistry::Register<LLXYVector> register_xy_vector("xy_vector");
+
+
+const F32 CENTER_CIRCLE_RADIUS = 2;
+const S32 ARROW_ANGLE = 30;
+const S32 ARROW_LENGTH_LONG = 10;
+const S32 ARROW_LENGTH_SHORT = 6;
+
+LLXYVector::Params::Params()
+ : x_entry("x_entry"),
+ y_entry("y_entry"),
+ touch_area("touch_area"),
+ border("border"),
+ edit_bar_height("edit_bar_height", 18),
+ padding("padding", 4),
+ min_val_x("min_val_x", -1.0f),
+ max_val_x("max_val_x", 1.0f),
+ increment_x("increment_x", 0.05f),
+ min_val_y("min_val_y", -1.0f),
+ max_val_y("max_val_y", 1.0f),
+ increment_y("increment_y", 0.05f),
+ label_width("label_width", 16),
+ arrow_color("arrow_color", LLColor4::white),
+ ghost_color("ghost_color"),
+ area_color("area_color", LLColor4::grey4),
+ grid_color("grid_color", LLColor4::grey % 0.25f)
+{
+}
+
+LLXYVector::LLXYVector(const LLXYVector::Params& p)
+ : LLUICtrl(p),
+ mArrowColor(p.arrow_color()),
+ mAreaColor(p.area_color),
+ mGridColor(p.grid_color),
+ mMinValueX(p.min_val_x),
+ mMaxValueX(p.max_val_x),
+ mIncrementX(p.increment_x),
+ mMinValueY(p.min_val_y),
+ mMaxValueY(p.max_val_y),
+ mIncrementY(p.increment_y)
+{
+ mGhostColor = p.ghost_color.isProvided() ? p.ghost_color() % 0.3f : p.arrow_color() % 0.3f;
+
+ LLRect border_rect = getLocalRect();
+ LLViewBorder::Params params = p.border;
+ params.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder>(params);
+ addChild(mBorder);
+
+ LLTextBox::Params x_label_params;
+ x_label_params.initial_value(p.x_entry.label());
+ x_label_params.rect = LLRect(p.padding,
+ border_rect.mTop - p.padding,
+ p.label_width,
+ border_rect.getHeight() - p.edit_bar_height);
+ mXLabel = LLUICtrlFactory::create<LLTextBox>(x_label_params);
+ addChild(mXLabel);
+ LLLineEditor::Params x_params = p.x_entry;
+ x_params.rect = LLRect(p.padding + p.label_width,
+ border_rect.mTop - p.padding,
+ border_rect.getCenterX(),
+ border_rect.getHeight() - p.edit_bar_height);
+ x_params.commit_callback.function(boost::bind(&LLXYVector::onEditChange, this));
+ mXEntry = LLUICtrlFactory::create<LLLineEditor>(x_params);
+ mXEntry->setPrevalidateInput(LLTextValidate::validateFloat);
+ addChild(mXEntry);
+
+ LLTextBox::Params y_label_params;
+ y_label_params.initial_value(p.y_entry.label());
+ y_label_params.rect = LLRect(border_rect.getCenterX() + p.padding,
+ border_rect.mTop - p.padding,
+ border_rect.getCenterX() + p.label_width,
+ border_rect.getHeight() - p.edit_bar_height);
+ mYLabel = LLUICtrlFactory::create<LLTextBox>(y_label_params);
+ addChild(mYLabel);
+ LLLineEditor::Params y_params = p.y_entry;
+ y_params.rect = LLRect(border_rect.getCenterX() + p.padding + p.label_width,
+ border_rect.getHeight() - p.padding,
+ border_rect.getWidth() - p.padding,
+ border_rect.getHeight() - p.edit_bar_height);
+ y_params.commit_callback.function(boost::bind(&LLXYVector::onEditChange, this));
+ mYEntry = LLUICtrlFactory::create<LLLineEditor>(y_params);
+ mYEntry->setPrevalidateInput(LLTextValidate::validateFloat);
+ addChild(mYEntry);
+
+ LLPanel::Params touch_area = p.touch_area;
+ touch_area.rect = LLRect(p.padding,
+ border_rect.mTop - p.edit_bar_height - p.padding,
+ border_rect.getWidth() - p.padding,
+ p.padding);
+ mTouchArea = LLUICtrlFactory::create<LLPanel>(touch_area);
+ addChild(mTouchArea);
+}
+
+LLXYVector::~LLXYVector()
+{
+}
+
+BOOL LLXYVector::postBuild()
+{
+ return TRUE;
+}
+
+void drawArrow(S32 tailX, S32 tailY, S32 tipX, S32 tipY, LLColor4 color)
+{
+ gl_line_2d(tailX, tailY, tipX, tipY, color);
+
+ S32 dx = tipX - tailX;
+ S32 dy = tipY - tailY;
+
+ S32 arrowLength = (abs(dx) < ARROW_LENGTH_LONG && abs(dy) < ARROW_LENGTH_LONG) ? ARROW_LENGTH_SHORT : ARROW_LENGTH_LONG;
+
+ F32 theta = std::atan2(dy, dx);
+
+ F32 rad = ARROW_ANGLE * std::atan(1) * 4 / 180;
+ F32 x = tipX - arrowLength * cos(theta + rad);
+ F32 y = tipY - arrowLength * sin(theta + rad);
+ F32 rad2 = -1 * ARROW_ANGLE * std::atan(1) * 4 / 180;
+ F32 x2 = tipX - arrowLength * cos(theta + rad2);
+ F32 y2 = tipY - arrowLength * sin(theta + rad2);
+ gl_triangle_2d(tipX, tipY, x, y, x2, y2, color, true);
+}
+
+void LLXYVector::draw()
+{
+ S32 centerX = mTouchArea->getRect().getCenterX();
+ S32 centerY = mTouchArea->getRect().getCenterY();
+
+ S32 pointX = centerX + (mValueX * mTouchArea->getRect().getWidth() / (2 * mMaxValueX));
+ S32 pointY = centerY + (mValueY * mTouchArea->getRect().getHeight() / (2 * mMaxValueY));
+
+ // fill
+ gl_rect_2d(mTouchArea->getRect(), mAreaColor, true);
+
+ // draw grid
+ gl_line_2d(centerX, mTouchArea->getRect().mTop, centerX, mTouchArea->getRect().mBottom, mGridColor);
+ gl_line_2d(mTouchArea->getRect().mLeft, centerY, mTouchArea->getRect().mRight, centerY, mGridColor);
+
+ // draw ghost
+ if (hasMouseCapture())
+ {
+ drawArrow(centerX, centerY, mGhostX, mGhostY, mGhostColor);
+ }
+ else
+ {
+ mGhostX = pointX;
+ mGhostY = pointY;
+ }
+
+ if (abs(mValueX) >= mIncrementX || abs(mValueY) >= mIncrementY)
+ {
+ // draw the vector arrow
+ drawArrow(centerX, centerY, pointX, pointY, mArrowColor);
+ }
+ else
+ {
+ // skip the arrow, set color for center circle
+ gGL.color4fv(mArrowColor.get().mV);
+ }
+
+ // draw center circle
+ gl_circle_2d(centerX, centerY, CENTER_CIRCLE_RADIUS, 12, true);
+
+ LLView::draw();
+}
+
+void LLXYVector::onEditChange()
+{
+ if (getEnabled())
+ {
+ setValueAndCommit(mXEntry->getValue().asReal(), mYEntry->getValue().asReal());
+ }
+}
+
+void LLXYVector::setValue(const LLSD& value)
+{
+ if (value.isArray())
+ {
+ setValue(value[0].asReal(), value[1].asReal());
+ }
+}
+
+void LLXYVector::setValue(F32 x, F32 y)
+{
+ x = llclamp(x, mMinValueX, mMaxValueX);
+ y = llclamp(y, mMinValueY, mMaxValueY);
+
+ // Round the values to nearest increments
+ x -= mMinValueX;
+ x += mIncrementX / 2.0001f;
+ x -= fmod(x, mIncrementX);
+ x += mMinValueX;
+
+ y -= mMinValueY;
+ y += mIncrementY / 2.0001f;
+ y -= fmod(y, mIncrementY);
+ y += mMinValueY;
+
+ mValueX = x;
+ mValueY = y;
+
+ update();
+}
+
+void LLXYVector::setValueAndCommit(F32 x, F32 y)
+{
+ if (mValueX != x || mValueY != y)
+ {
+ setValue(x, y);
+ onCommit();
+ }
+}
+
+LLSD LLXYVector::getValue() const
+{
+ LLSD value;
+ value.append(mValueX);
+ value.append(mValueY);
+ return value;
+}
+
+void LLXYVector::update()
+{
+ mXEntry->setValue(mValueX);
+ mYEntry->setValue(mValueY);
+}
+
+BOOL LLXYVector::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (hasMouseCapture())
+ {
+ F32 valueX = F32(x - mTouchArea->getRect().getCenterX()) / mTouchArea->getRect().getWidth();
+ F32 valueY = F32(y - mTouchArea->getRect().getCenterY()) / mTouchArea->getRect().getHeight();
+
+ valueX *= 2 * mMaxValueX;
+ valueY *= 2 * mMaxValueY;
+
+ setValueAndCommit(valueX, valueY);
+ }
+
+ return TRUE;
+}
+
+BOOL LLXYVector::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ if (hasMouseCapture())
+ {
+ gFocusMgr.setMouseCapture(NULL);
+ make_ui_sound("UISndClickRelease");
+ }
+
+ return TRUE;
+}
+
+BOOL LLXYVector::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+
+ if (mTouchArea->getRect().pointInRect(x, y))
+ {
+ gFocusMgr.setMouseCapture(this);
+ make_ui_sound("UISndClick");
+ }
+
+ return TRUE;
+}
+
diff --git a/indra/llui/llxyvector.h b/indra/llui/llxyvector.h
new file mode 100644
index 0000000000..4d67db3251
--- /dev/null
+++ b/indra/llui/llxyvector.h
@@ -0,0 +1,118 @@
+/**
+* @file llxyvector.h
+* @author Andrey Lihatskiy
+* @brief Header file for LLXYVector
+*
+* $LicenseInfo:firstyear=2001&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$
+*/
+
+// A control that allows to set two related vector magnitudes by manipulating a single vector on a plane.
+
+#ifndef LL_LLXYVECTOR_H
+#define LL_LLXYVECTOR_H
+
+#include "lluictrl.h"
+#include "llpanel.h"
+#include "lltextbox.h"
+#include "lllineeditor.h"
+
+class LLXYVector
+ : public LLUICtrl
+{
+public:
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLLineEditor::Params> x_entry;
+ Optional<LLLineEditor::Params> y_entry;
+ Optional<LLPanel::Params> touch_area;
+ Optional<LLViewBorder::Params> border;
+ Optional<S32> edit_bar_height;
+ Optional<S32> padding;
+ Optional<S32> label_width;
+ Optional<F32> min_val_x;
+ Optional<F32> max_val_x;
+ Optional<F32> increment_x;
+ Optional<F32> min_val_y;
+ Optional<F32> max_val_y;
+ Optional<F32> increment_y;
+ Optional<LLUIColor> arrow_color;
+ Optional<LLUIColor> ghost_color;
+ Optional<LLUIColor> area_color;
+ Optional<LLUIColor> grid_color;
+
+ Params();
+ };
+
+
+ virtual ~LLXYVector();
+ /*virtual*/ BOOL postBuild();
+
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+ virtual void draw();
+
+ virtual void setValue(const LLSD& value);
+ void setValue(F32 x, F32 y);
+ virtual LLSD getValue() const;
+
+protected:
+ friend class LLUICtrlFactory;
+ LLXYVector(const Params&);
+ void onEditChange();
+
+protected:
+ LLTextBox* mXLabel;
+ LLTextBox* mYLabel;
+ LLLineEditor* mXEntry;
+ LLLineEditor* mYEntry;
+ LLPanel* mTouchArea;
+ LLViewBorder* mBorder;
+
+private:
+ void update();
+ void setValueAndCommit(F32 x, F32 y);
+
+ F32 mValueX;
+ F32 mValueY;
+
+ F32 mMinValueX;
+ F32 mMaxValueX;
+ F32 mIncrementX;
+ F32 mMinValueY;
+ F32 mMaxValueY;
+ F32 mIncrementY;
+
+ U32 mGhostX;
+ U32 mGhostY;
+
+ LLUIColor mArrowColor;
+ LLUIColor mGhostColor;
+ LLUIColor mAreaColor;
+ LLUIColor mGridColor;
+
+};
+
+#endif
+
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2fc722d4c3..e80bb5f4a5 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -159,7 +159,6 @@ set(viewer_SOURCE_FILES
llcurrencyuimanager.cpp
llcylinder.cpp
lldateutil.cpp
- lldaycyclemanager.cpp
lldebugmessagebox.cpp
lldebugview.cpp
lldeferredsounds.cpp
@@ -182,7 +181,7 @@ set(viewer_SOURCE_FILES
lldrawpoolwlsky.cpp
lldynamictexture.cpp
llemote.cpp
- llenvmanager.cpp
+ llenvironment.cpp
llestateinfomodel.cpp
lleventnotifier.cpp
lleventpoll.cpp
@@ -222,18 +221,16 @@ set(viewer_SOURCE_FILES
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
- llfloaterdeleteenvpreset.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
llfloatereditdaycycle.cpp
- llfloatereditsky.cpp
- llfloatereditwater.cpp
- llfloaterenvironmentsettings.cpp
+ llfloatereditextdaycycle.cpp
llfloaterevent.cpp
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
llfloaterfacebook.cpp
+ llfloaterfixedenvironment.cpp
llfloaterflickr.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
@@ -264,6 +261,7 @@ set(viewer_SOURCE_FILES
llfloatermemleak.cpp
llfloatermodelpreview.cpp
llfloatermodeluploadbase.cpp
+ llfloatermyenvironment.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
@@ -319,6 +317,7 @@ set(viewer_SOURCE_FILES
llfolderviewmodelinventory.cpp
llfollowcam.cpp
llfriendcard.cpp
+ llflyoutcombobtn.cpp
llgesturelistener.cpp
llgesturemgr.cpp
llgiveinventory.cpp
@@ -366,6 +365,7 @@ set(viewer_SOURCE_FILES
lljoystickbutton.cpp
lllandmarkactions.cpp
lllandmarklist.cpp
+ lllegacyatmospherics.cpp
lllistbrowser.cpp
lllistcontextmenu.cpp
lllistview.cpp
@@ -421,7 +421,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
@@ -536,6 +539,8 @@ set(viewer_SOURCE_FILES
llsecapi.cpp
llsechandler_basic.cpp
llselectmgr.cpp
+ llsettingspicker.cpp
+ llsettingsvo.cpp
llshareavatarhandler.cpp
llsidepanelappearance.cpp
llsidepanelinventory.cpp
@@ -690,19 +695,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
@@ -781,7 +780,6 @@ set(viewer_HEADER_FILES
llcurrencyuimanager.h
llcylinder.h
lldateutil.h
- lldaycyclemanager.h
lldebugmessagebox.h
lldebugview.h
lldeferredsounds.h
@@ -804,7 +802,7 @@ set(viewer_HEADER_FILES
lldrawpoolwlsky.h
lldynamictexture.h
llemote.h
- llenvmanager.h
+ llenvironment.h
llestateinfomodel.h
lleventnotifier.h
lleventpoll.h
@@ -845,17 +843,14 @@ set(viewer_HEADER_FILES
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloaterdeleteprefpreset.h
- llfloaterdeleteenvpreset.h
llfloaterdestinations.h
- llfloatereditdaycycle.h
- llfloatereditsky.h
- llfloatereditwater.h
- llfloaterenvironmentsettings.h
+ llfloatereditextdaycycle.h
llfloaterevent.h
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
llfloaterfacebook.h
+ llfloaterfixedenvironment.h
llfloaterflickr.h
llfloaterfonttest.h
llfloatergesture.h
@@ -889,6 +884,7 @@ set(viewer_HEADER_FILES
llfloatermemleak.h
llfloatermodelpreview.h
llfloatermodeluploadbase.h
+ llfloatermyenvironment.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
@@ -944,6 +940,7 @@ set(viewer_HEADER_FILES
llfolderviewmodelinventory.h
llfollowcam.h
llfriendcard.h
+ llflyoutcombobtn.h
llgesturelistener.h
llgesturemgr.h
llgiveinventory.h
@@ -1036,7 +1033,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
@@ -1150,6 +1150,8 @@ set(viewer_HEADER_FILES
llsecapi.h
llsechandler_basic.h
llselectmgr.h
+ llsettingspicker.h
+ llsettingsvo.h
llsidepanelappearance.h
llsidepanelinventory.h
llsidepanelinventorysubpanel.h
@@ -1306,19 +1308,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
@@ -2379,7 +2375,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/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8e8cce5787..83afa0ed8c 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>
@@ -6617,6 +6628,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>
@@ -9044,7 +9066,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>-0.008</real>
+ <real>-0.004</real>
</map>
<key>RenderShadowOffset</key>
<map>
@@ -10145,6 +10167,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>
@@ -15646,6 +15679,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>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index b9c8f34cb0..7f2c5add16 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -39,19 +39,6 @@ out vec4 frag_color;
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;
@@ -84,12 +71,6 @@ VARYING vec3 vary_norm;
VARYING vec4 vertex_color;
#endif
-vec3 vary_PositionEye;
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
uniform mat4 inv_proj;
uniform vec2 screen_res;
@@ -98,59 +79,20 @@ uniform vec3 light_direction[8];
uniform vec3 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);
-#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
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec2 encode_normal (vec3 n);
+vec3 decode_normal (vec2 enc);
-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 scaleFragSoftClip(vec3 l);
+vec3 atmosFragAmbient(vec3 light, vec3 sunlit);
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+vec3 atmosFragAffectDirectionalLight(float light, vec3 sunlit);
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
vec3 calcDirectionalLight(vec3 n, vec3 l)
{
@@ -219,237 +161,6 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
}
#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
-
-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));
-}
-
-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;
-}
void main()
{
@@ -566,7 +277,12 @@ void main()
vec3 norm = vary_norm;
- calcAtmospherics(pos.xyz, 1.0);
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten);
vec2 abnormal = encode_normal(norm.xyz);
norm.xyz = decode_normal(abnormal.xy);
@@ -581,7 +297,7 @@ void main()
vec4 color = vec4(0,0,0,0);
- color.rgb = atmosAmbient(color.rgb);
+ color.rgb = atmosFragAmbient(color.rgb, amblit);
color.a = final_alpha;
float ambient = abs(da);
@@ -590,13 +306,13 @@ void main()
ambient = (1.0-ambient);
color.rgb *= ambient;
- color.rgb += atmosAffectDirectionalLight(final_da);
+ color.rgb += atmosFragAffectDirectionalLight(final_da, sunlit);
color.rgb *= gamma_diff.rgb;
//color.rgb = mix(diff.rgb, color.rgb, final_alpha);
- color.rgb = atmosLighting(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
+ color.rgb = atmosFragLighting(color.rgb, additive, atten);
+ color.rgb = scaleFragSoftClip(color.rgb);
vec4 light = vec4(0,0,0,0);
@@ -621,9 +337,8 @@ void main()
color.rgb = linear_to_srgb(color.rgb);
#ifdef WATER_FOG
- color = applyWaterFogDeferred(pos.xyz, color);
+ color = applyWaterFogView(pos.xyz, color);
#endif
-
#endif
frag_color = color;
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/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..8e46425ea8 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
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index cbd8d2ebfc..b56abb66d1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -61,22 +61,7 @@ vec4 getPosition(vec2 pos_screen)
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;
-}
+vec3 decode_normal (vec2 enc);
void main()
{
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/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index 1d8ca04ccd..c1a9a6f454 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -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,6 +39,8 @@ 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;
@@ -49,12 +51,14 @@ VARYING vec2 vary_texcoord2;
VARYING vec2 vary_texcoord3;
/// 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()
@@ -77,17 +81,21 @@ void main()
// 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;
+ 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 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
// And smooth
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..828c325c9d 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,12 +35,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/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 756e625d07..0e21e5925d 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
@@ -41,43 +41,12 @@ 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 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
vec3 fullbrightAtmosTransportDeferred(vec3 light)
{
@@ -94,52 +63,6 @@ vec3 fullbrightScaleSoftClipDeferred(vec3 light)
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
@@ -166,7 +89,7 @@ void main()
#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
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index b0db9876d3..30e560450b 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;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index f8fdde43f9..6ba16b169c 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 cl);
void main()
{
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..6e06453a5b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#define DIFFUSE_ALPHA_MODE_IGNORE 0
#define DIFFUSE_ALPHA_MODE_BLEND 1
#define DIFFUSE_ALPHA_MODE_MASK 2
@@ -31,42 +33,18 @@
uniform float emissive_brightness;
uniform float display_gamma;
-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 cs);
+vec3 linear_to_srgb(vec3 cl);
-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 atmosFragAmbient(vec3 l, vec3 ambient);
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleFragSoftClip(vec3 l);
+vec3 atmosFragAffectDirectionalLight(float intensity, vec3 sunlit);
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
@@ -116,19 +94,6 @@ 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;
@@ -137,13 +102,6 @@ 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 inv_proj;
uniform vec2 screen_res;
@@ -152,52 +110,6 @@ uniform vec3 light_direction[8];
uniform vec3 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);
@@ -283,198 +195,6 @@ vec4 getPosition_d(vec2 pos_screen, float depth)
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;
-}
-
-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));
-}
-
-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;
-}
#else
#ifdef DEFINE_GL_FRAGCOLOR
@@ -515,22 +235,8 @@ 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;
-}
-
-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);
+vec3 decode_normal (vec2 enc);
void main()
{
@@ -673,7 +379,12 @@ void main()
vec3 col = vec3(0.0f,0.0f,0.0f);
float bloom = 0.0;
- calcAtmospherics(pos.xyz, 1.0);
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten);
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
@@ -686,7 +397,7 @@ void main()
final_da = min(final_da, 1.0f);
final_da = pow(final_da, 1.0/1.3);
- col.rgb = atmosAmbient(col);
+ col.rgb = atmosFragAmbient(col, amblit);
float ambient = min(abs(da), 1.0);
ambient *= 0.5;
@@ -695,7 +406,7 @@ void main()
col.rgb *= ambient;
- col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
+ col.rgb = col.rgb + atmosFragAffectDirectionalLight(final_da, sunlit);
col.rgb *= gamma_diff.rgb;
@@ -707,8 +418,9 @@ void main()
// 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);
+ float sa = dot(refnormpersp, sun_dir.xyz);
+
+ vec3 dumbshiny = sunlit*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
@@ -742,8 +454,8 @@ void main()
//col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
//col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
- col = atmosLighting(col);
- col = scaleSoftClip(col);
+ col = atmosFragLighting(col, additive, atten);
+ col = scaleFragSoftClip(col);
//convert to linear space before adding local lights
col = srgb_to_linear(col);
@@ -771,7 +483,7 @@ void main()
col.rgb = linear_to_srgb(col.rgb);
#ifdef WATER_FOG
- vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
+ vec4 temp = applyWaterFogView(pos, vec4(col.rgb, al));
col.rgb = temp.rgb;
al = temp.a;
#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..e86bca3ddd
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -0,0 +1,66 @@
+/**
+ * @file moonF.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 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+uniform vec4 color;
+uniform vec4 sunlight_color;
+uniform vec3 lumWeights;
+uniform float minLuminance;
+uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between moon A/B
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(moonA, moonB, blend_factor);
+
+ c.rgb = pow(c.rgb, vec3(0.7f));
+ c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+
+ // mix factor which blends when sunlight is brighter
+ // and shows true moon color at night
+ vec3 luma_weights = vec3(0.1, 0.3, 0.0);
+ float mix = 1.0f - dot(sunlight_color.rgb, luma_weights);
+ frag_data[0] = vec4(c.rgb, mix * c.a);
+ frag_data[1] = vec4(0.0);
+ frag_data[2] = vec4(0.0f);
+}
+
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..0325ecead9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
@@ -0,0 +1,48 @@
+/**
+ * @file moonV.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;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz, 1.0);
+ vec4 pos = (modelview_matrix * vert);
+
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+
+ calcAtmospherics(pos.xyz);
+
+ 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..d1ac19270d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -57,22 +57,7 @@ uniform float far_z;
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 decode_normal (vec2 enc);
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 3a3e871ade..1d75322b4c 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;
@@ -72,59 +72,9 @@ 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 decode_normal (vec2 enc);
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index aba4a01754..13b803e03e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -56,22 +56,7 @@ 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;
-}
+vec3 decode_normal (vec2 enc);
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 6669947d1b..cbc19bbba3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -40,25 +40,7 @@ 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()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
index 018ced4cad..e33254304b 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
diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
index 1211505273..12bc690553 100644
--- a/indra/newview/llfloaterdeleteenvpreset.h
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
@@ -1,6 +1,5 @@
/**
- * @file llfloaterdeleteenvpreset.h
- * @brief Floater to delete a water / sky / day cycle preset.
+ * @file shadowAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,39 +23,33 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLFLOATERDELETEENVPRESET_H
-#define LL_LLFLOATERDELETEENVPRESET_H
+/*[EXTRA_CODE_HERE]*/
-#include "llfloater.h"
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
-class LLComboBox;
+uniform sampler2D diffuseMap;
-class LLFloaterDeleteEnvPreset : public LLFloater
-{
- LOG_CLASS(LLFloaterDeleteEnvPreset);
-
-public:
- LLFloaterDeleteEnvPreset(const LLSD &key);
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
-
- void onBtnDelete();
- void onBtnCancel();
+#if !DEPTH_CLAMP
+VARYING float pos_zd2;
+#endif
-private:
- void populatePresetsList();
- void populateWaterPresetsList();
- void populateSkyPresetsList();
- void populateDayCyclesList();
+VARYING float pos_w;
- void postPopulate();
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
- void onDeleteDayCycleConfirmation();
- void onDeleteSkyPresetConfirmation();
- void onDeleteWaterPresetConfirmation();
-
- LLComboBox* mPresetCombo;
-};
-
-#endif // LL_LLFLOATERDELETEENVPRESET_H
+void main()
+{
+ float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+
+ frag_color = vec4(alpha, alpha, alpha, 1);
+
+#if !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..11411a605c
--- /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 !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 !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..ae1b19a35c 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
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 3d1b182875..242aef821d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.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/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 22f4729e2e..0613111632 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,17 +37,10 @@ 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);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 03bdb754b5..7a1968efee 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
@@ -51,83 +51,32 @@ 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;
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);
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-}
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec3 decode_normal (vec2 enc);
-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));
+vec3 atmosFragAmbient(vec3 l, vec3 ambient);
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleFragSoftClip(vec3 l);
+vec3 atmosFragAffectDirectionalLight(float intensity, vec3 sunlit);
+vec3 fullbrightFragAtmosTransport(vec3 l, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClipFrag(vec3 l, vec3 atten);
-#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;
-}
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
vec4 getPosition_d(vec2 pos_screen, float depth)
{
@@ -147,243 +96,6 @@ vec4 getPosition(vec2 pos_screen)
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;
-}
-
-
-#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 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()
{
@@ -397,7 +109,9 @@ void main()
float da = dot(norm.xyz, sun_dir.xyz);
float final_da = max(0.0,da);
- final_da = min(final_da, 1.0f);
+ final_da = min(final_da, 1.0f);
+
+// why an ad hoc gamma boost here? srgb_to_linear instead?
final_da = pow(final_da, 1.0/1.3);
vec4 diffuse = texture2DRect(diffuseRect, tc);
@@ -409,9 +123,13 @@ void main()
vec3 col;
float bloom = 0.0;
{
- calcAtmospherics(pos.xyz, 1.0);
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten);
- col = atmosAmbient(vec3(0));
+ col = atmosFragAmbient(vec3(0), amblit);
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
ambient *= 0.5;
ambient *= ambient;
@@ -419,7 +137,7 @@ void main()
col.rgb *= ambient;
- col += atmosAffectDirectionalLight(final_da);
+ col += atmosFragAffectDirectionalLight(final_da, sunlit);
col *= diffuse.rgb;
@@ -431,7 +149,8 @@ void main()
//
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
+
+ vec3 dumbshiny = sunlit*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
@@ -455,12 +174,13 @@ void main()
if (norm.w < 0.5)
{
- col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+ vec3 add = additive * spec.a;
+ col = mix(atmosFragLighting(col, add, atten), fullbrightFragAtmosTransport(col, atten, add), diffuse.a);
+ col = mix(scaleFragSoftClip(col), fullbrightScaleSoftClipFrag(col, atten), diffuse.a);
}
#ifdef WATER_FOG
- vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+ vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
col = fogged.rgb;
bloom = fogged.a;
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index f1aec315cc..2b6428963d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -70,59 +70,9 @@ 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 decode_normal (vec2 enc);
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
vec4 correctWithGamma(vec4 col)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index 821058804c..4ae3f7b76f 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,34 @@ 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 vec4 sunlight_color;
+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);
-
+ 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,0,0,0);
- frag_data[2] = vec4(0,0,1,0);
+ frag_data[1] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
index 8bc5b06379..e14d02a4a9 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,14 @@ 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);
+ 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..3557c0766e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -0,0 +1,57 @@
+/**
+ * @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 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;
+
+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 = clamp(c.rgb, vec3(0), vec3(1));
+ c.rgb = pow(c.rgb, vec3(0.7f));
+ c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+ frag_data[0] = c;
+ frag_data[1] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+}
+
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..c67ed8e6d9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
@@ -0,0 +1,48 @@
+/**
+ * @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;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz - vec3(0, 0, 50), 1.0);
+ vec4 pos = modelview_projection_matrix*vert;
+
+ 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..403df87853 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -51,22 +51,7 @@ 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;
-}
+vec3 decode_normal (vec2 enc);
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 52a429465f..0cd90b0d97 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -39,11 +41,7 @@ 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()
{
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..db1eab23fb 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,48 +58,10 @@ 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
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
vec4 applyWaterFog(vec4 color, vec3 viewVec)
{
@@ -151,7 +115,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
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 37dcd3ad34..a29acb3e7d 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,6 +37,8 @@ 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;
@@ -69,47 +71,16 @@ 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 srgb_to_linear(vec3 cs);
+vec2 encode_normal(vec3 n);
-vec3 linear_to_srgb(vec3 cl)
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
{
- 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 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()
@@ -121,9 +92,19 @@ 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;
+ 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(
@@ -186,6 +167,7 @@ void main()
//mix with reflection
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
+ refcol.rgb = pow(refcol.rgb, vec3(0.45)); // boost the reflect color a little to get stars to show up SL-1475
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
vec4 pos = vary_position;
diff --git a/indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl
new file mode 100644
index 0000000000..becc6d89c1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file decodeNormF.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$
+ */
+
+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;
+}
+
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..50e781fa78
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
@@ -0,0 +1,31 @@
+/**
+ * @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$
+ */
+
+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..835662732a 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,17 @@ 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
+
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 0d8dab0a41..e918bdcb9d 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -56,41 +56,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 +74,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..19158f4505 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterF.glsl
+ * @file class1/environment/waterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,6 +33,8 @@ vec3 scaleSoftClip(vec3 inColor);
vec3 atmosTransport(vec3 inColor);
uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
uniform sampler2D screenTex;
uniform sampler2D refTex;
@@ -55,6 +57,15 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+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;
@@ -65,9 +76,18 @@ 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;
+ 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(
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 4bdfce9260..68ce2843d0 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -25,7 +25,6 @@
-uniform vec4 lightnorm;
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
@@ -33,10 +32,10 @@ uniform float waterFogKS;
vec3 getPositionEye();
-vec4 applyWaterFog(vec4 color)
+vec4 applyWaterFogView(vec3 pos, vec4 color)
{
+ vec3 view = normalize(pos);
//normalize view vector
- vec3 view = normalize(getPositionEye());
float es = -(dot(view, waterPlane.xyz));
//find intersection point with water plane and eye vector
@@ -47,7 +46,7 @@ vec4 applyWaterFog(vec4 color)
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);
+ float depth = length(pos - int_v);
//get "thickness" of water
float l = max(depth, 0.1);
@@ -72,3 +71,9 @@ vec4 applyWaterFog(vec4 color)
return color;
}
+vec4 applyWaterFog(vec4 color)
+{
+ //normalize view vector
+ return applyWaterFogView(getPositionEye(), color);
+}
+
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/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/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index aacc503e13..584bd568c5 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
@@ -31,3 +31,8 @@ vec3 atmosLighting(vec3 light)
return light;
}
+
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor) {
+ /* stub function for fallback compatibility on class1 hardware */
+}
+
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..3f70a8935b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
@@ -0,0 +1,55 @@
+/**
+ * @file 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;
+
+vec3 atmosAmbient(vec3 light)
+{
+ return light + 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;
+}
+
+vec3 scaleUpLight(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..89b6a52909 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -23,7 +23,7 @@
* $/LicenseInfo$
*/
-uniform vec4 sunlight_color_copy;
+uniform vec4 sunlight_color;
uniform vec4 light_ambient;
vec3 atmosAmbient(vec3 light)
@@ -33,12 +33,12 @@ vec3 atmosAmbient(vec3 light)
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)
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..933625986c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -0,0 +1,63 @@
+/**
+ * @file moonF.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 vec4 color;
+uniform vec4 sunlight_color;
+uniform vec3 lumWeights;
+uniform float minLuminance;
+uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between moon A/B
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(moonA, moonB, blend_factor);
+
+ c.rgb = pow(c.rgb, vec3(0.45f));
+ c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+ // mix factor which blends when sunlight is brighter
+ // and shows true moon color at night
+ vec3 luma_weights = vec3(0.1, 0.3, 0.0);
+ float mix = 1.0f - dot(sunlight_color.rgb, luma_weights);
+ frag_color = vec4(c.rgb, mix * 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..aaa6768ed7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
@@ -0,0 +1,48 @@
+/**
+ * @file moonV.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;
+
+void calcAtmospherics(vec3 inPositionEye);
+
+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*vec4(position.xyz, 1.0);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+ calcAtmospherics(pos.xyz);
+}
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..3f2375ee4d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
@@ -0,0 +1,54 @@
+/**
+ * @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_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;
+
+void main()
+{
+ vec4 sunA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 sunB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(sunA, sunB, blend_factor);
+ c.rgb = pow(c.rgb, vec3(0.7f));
+ 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..dd33a4be60
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
@@ -0,0 +1,48 @@
+/**
+ * @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;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz - vec3(0, 0, 50), 1.0);
+ vec4 pos = modelview_projection_matrix*vert;
+
+ gl_Position = pos;
+
+ calcAtmospherics(pos.xyz);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index b9bb522842..864ba4859d 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -71,59 +71,9 @@ 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;
-}
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec3 decode_normal (vec2 enc);
vec4 correctWithGamma(vec4 col)
{
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index f7832521fa..c7950a2a31 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -49,7 +49,6 @@ 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;
@@ -70,69 +69,20 @@ uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
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 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 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec3 decode_normal (vec2 enc);
-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 atmosFragAmbient(vec3 l, vec3 ambient);
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleFragSoftClip(vec3 l);
+vec3 atmosFragAffectDirectionalLight(float intensity, vec3 sunlit);
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
+vec3 fullbrightFragAtmosTransport(vec3 l, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClipFrag(vec3 l, vec3 atten);
vec4 getPosition_d(vec2 pos_screen, float depth)
{
@@ -152,247 +102,11 @@ vec4 getPosition(vec2 pos_screen)
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));
-}
#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
-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;
@@ -426,10 +140,15 @@ void main()
float ambocc = scol_ambocc.g;
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
- calcAtmospherics(pos.xyz, ambocc);
+ calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten);
- col = atmosAmbient(vec3(0));
+ col = atmosFragAmbient(vec3(0), amblit);
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
ambient *= 0.5;
ambient *= ambient;
@@ -437,7 +156,7 @@ void main()
col.rgb *= ambient;
- col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
+ col += atmosFragAffectDirectionalLight(max(min(da, scol), 0.0), sunlit);
col *= diffuse.rgb;
@@ -446,10 +165,8 @@ void main()
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);
+ vec3 dumbshiny = sunlit*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
@@ -463,22 +180,19 @@ void main()
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);
-
+ 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);
+ vec3 add = additive * spec.a;
+ col = mix(atmosFragLighting(col, add, atten), fullbrightFragAtmosTransport(col, atten, add), diffuse.a);
+ col = mix(scaleFragSoftClip(col), fullbrightScaleSoftClipFrag(col, atten), diffuse.a);
}
#ifdef WATER_FOG
- vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+ vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
col = fogged.rgb;
bloom = fogged.a;
#endif
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 81af1fdc8a..a7da140b31 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -71,59 +71,9 @@ 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 decode_normal (vec2 enc);
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
vec4 correctWithGamma(vec4 col)
{
@@ -238,8 +188,8 @@ 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 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;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 265da8df99..aa5e99a2f7 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -67,22 +67,7 @@ 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;
-}
+vec3 decode_normal (vec2 enc);
vec4 getPosition(vec2 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..58f3f2f91e 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -68,22 +68,7 @@ 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;
-}
+vec3 decode_normal (vec2 enc);
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index fea3cbf69b..4ec5691a85 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
@@ -22,23 +22,135 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
vec3 getAdditiveColor();
vec3 getAtmosAttenuation();
uniform sampler2D cloudMap;
+uniform vec4 gamma;
uniform vec4 cloud_pos_density1;
+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 ssao_effect_mat;
+uniform int no_atmo;
-vec3 atmosLighting(vec3 light)
+vec3 scaleFragSoftClip(vec3 light)
+{
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ //soft clip effect:
+ light = 1. - clamp(light, vec3(0.), vec3(1.));
+ light = 1. - pow(light, gamma.xxx);
+ return light;
+}
+
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
+ if (no_atmo == 0)
+ {
+ light *= atten.r;
+ light += additive;
+ }
return (2.0 * light);
}
+vec3 atmosLighting(vec3 light)
+{
+ return (no_atmo == 1) ? light : atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
+}
+
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten) {
+
+ vec3 P = inPositionEye;
+
+ 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
+ atten = 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
+ additive =
+ 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
+ sunlit = vec3(sunlight * .5);
+ amblit = vec3(tmpAmbient * .25);
+ additive *= vec3(1.0 - temp1);
+}
+
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..3582759e62
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
@@ -0,0 +1,49 @@
+/**
+ * @file 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;
+
+vec3 atmosFragAmbient(vec3 light, vec3 amblit)
+{
+ return amblit + light / 2.0;
+}
+
+vec3 atmosFragAffectDirectionalLight(float lightIntensity, vec3 sunlit)
+{
+ return sunlit * lightIntensity;
+}
+
+vec3 scaleDownLightFrag(vec3 light)
+{
+ return (light / scene_light_strength );
+}
+
+vec3 scaleUpLightFrag(vec3 light)
+{
+ return (light * scene_light_strength);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
index 99dbee15ee..414ba3236a 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
@@ -73,6 +73,9 @@ void setAmblitColor(vec3 v)
void setAdditiveColor(vec3 v)
{
+ // SL-1491 clamp additive term to something reasonable to prevent
+ // lens flares over non-reflective surfaces
+ v = clamp(v, vec3(0), vec3(0.8));
additive_color = v;
vary_AdditiveColor = v;
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 96c70651b1..24fdb45749 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -42,17 +42,21 @@ 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;
/// 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 samp = mix(a, b, blend_factor);
+ return samp;
}
void main()
@@ -75,7 +79,7 @@ void main()
// 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;
+ 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
@@ -85,7 +89,7 @@ void main()
// 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);
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
// And smooth
diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
index 478373d729..f2764b72c3 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
@@ -26,11 +26,16 @@
uniform vec4 gamma;
+uniform int no_atmo;
vec3 getAtmosAttenuation();
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light) {
+ if (no_atmo == 1)
+ {
+ return light;
+ }
//soft clip effect:
light = 1. - clamp(light, vec3(0.), vec3(1.));
light = 1. - pow(light, gamma.xxx);
@@ -38,7 +43,12 @@ vec3 scaleSoftClip(vec3 light) {
return light;
}
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 atten)
+{
+ return (no_atmo == 1) ? light : mix(scaleSoftClip(light.rgb), light.rgb, atten);
+}
+
vec3 fullbrightScaleSoftClip(vec3 light) {
- return mix(scaleSoftClip(light.rgb), light.rgb, getAtmosAttenuation());
+ return (no_atmo == 1) ? light : fullbrightScaleSoftClipFrag(light.rgb, 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..28d185b9af 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,10 @@ 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()
{
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index 8a8e4cb0f6..9627642b9d 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
@@ -32,22 +32,43 @@ 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 atmosFragTransport(vec3 light, vec3 atten, vec3 additive) {
+ if (no_atmo == 0)
+ {
+ light *= atten.r;
+ light += additive * 2.0;
+ }
return light;
}
-vec3 fullbrightAtmosTransport(vec3 light) {
+vec3 fullbrightFragAtmosTransport(vec3 light, vec3 atten, vec3 additive) {
+ if (no_atmo == 1)
+ {
+ return light;
+ }
float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+ return mix(atmosFragTransport(light.rgb, atten, additive), light.rgb + additive.rgb, brightness * brightness);
}
-vec3 fullbrightShinyAtmosTransport(vec3 light) {
+vec3 fullbrightFragShinyAtmosTransport(vec3 light, vec3 atten, vec3 additive) {
+ if (no_atmo == 1)
+ {
+ return light;
+ }
float brightness = dot(light.rgb, vec3(0.33333));
+ return mix(atmosFragTransport(light.rgb, atten, additive), (light.rgb + additive.rgb) * (2.0 - brightness), brightness * brightness);
+}
- return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
+vec3 atmosTransport(vec3 light) {
+ return (no_atmo == 1) ? light : atmosFragTransport(light, getAtmosAttenuation(), getAdditiveColor());
}
+vec3 fullbrightAtmosTransport(vec3 light) {
+ return (no_atmo == 1) ? light : fullbrightFragAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor());
+}
+
+vec3 fullbrightShinyAtmosTransport(vec3 light) {
+ return (no_atmo == 1) ? light : fullbrightFragShinyAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor());
+}
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..d9fcc0a9ea
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
@@ -0,0 +1,109 @@
+/**
+ * @file WLCloudsF.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
+
+/////////////////////////////////////////////////////////////////////////
+// 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;
+
+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;
+
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 samp = mix(a, b, blend_factor);
+ return samp;
+}
+
+
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light);
+
+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 = (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;
+
+
+ // 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 *= 2.;
+
+ /// Gamma correct for WL (soft clip effect).
+ frag_color.rgb = scaleSoftClip(color.rgb);
+ frag_color.a = alpha1;
+}
+
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..c1dd45cd67
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
@@ -0,0 +1,190 @@
+/**
+ * @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;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+//////////////////////////////////////////////////////////////////////////
+// The vertex shader for creating the atmospheric sky
+///////////////////////////////////////////////////////////////////////////////
+
+// Output parameters
+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;
+
+// Inputs
+uniform vec3 camPosLocal;
+
+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 max_y;
+
+uniform vec4 glow;
+
+uniform vec4 cloud_color;
+
+uniform float cloud_scale;
+
+void main()
+{
+
+ // World / view / projection
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ vary_texcoord0 = texcoord0;
+
+ // Get relative position
+ vec3 P = position.xyz - camPosLocal.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;
+
+ // 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)
+ );
+
+ // CLOUDS
+
+ sunlight = sunlight_color;
+ temp2.y = max(0., lightnorm.y * 2.);
+ temp2.y = 1. / temp2.y;
+ sunlight *= exp( - light_atten * temp2.y);
+
+ // Cloud color out
+ vary_CloudColorSun = (sunlight * temp2.x) * 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);
+
+ // 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;
+
+ // needs this to compile on mac
+ //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+
+ // END CLOUDS
+}
+
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..864ba4859d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -0,0 +1,314 @@
+/**
+ * @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 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec3 decode_normal (vec2 enc);
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(srgb_to_linear(col.rgb), col.a);
+}
+
+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);
+
+ 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);
+ 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 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 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;
+}
+
+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)
+ {
+ 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/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
new file mode 100644
index 0000000000..7bfc114383
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
@@ -0,0 +1,83 @@
+/**
+ * @file class3/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;
+
+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);
+
+void main()
+{
+ vec3 pos = vec3((vary_frag * 2.0) - vec2(1.0, 1.0), 0.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;
+
+ vec3 view_direction = normalize(view_ray);
+ vec3 sun_direction = normalize(sun_dir);
+
+ vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f);
+ vec3 transmittance;
+ vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance);
+ vec3 solar_luminance = transmittance * 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;
+ }
+ s = smoothstep(0.9, 1.0, s) * 16.0f;
+
+ vec3 color = vec3(1.0) - exp(-radiance_sun * 0.0001);
+
+ 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..a5cc49ca30
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file 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 vec3 cameraPosLocal;
+uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
+uniform mat4 inv_proj;
+uniform mat4 inv_modelview;
+
+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..d2fd70c9e2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -0,0 +1,189 @@
+/**
+ * @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 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 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;
+VARYING vec2 vary_fragcoord;
+
+uniform mat4 inv_proj;
+uniform mat4 inv_modelview;
+
+uniform vec2 screen_res;
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec3 decode_normal (vec2 enc);
+
+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);
+}
+
+
+#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 = 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;
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ //calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten);
+ //col += atmosFragAffectDirectionalLight(max(min(da, scol), 0.0), sunlit);
+
+ 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 = 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;
+ 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(atmosFragLighting(col, additive, atten), fullbrightFragAtmosTransport(col, atten, additive), diffuse.a);
+ //col = mix(scaleFragSoftClip(col), fullbrightScaleSoftClipFrag(col, atten), diffuse.a);
+ }
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ col = srgb_to_linear(col);
+ }
+
+ 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..c840d72784
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+uniform vec2 screen_res;
+
+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;
+}
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..a7da140b31
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -0,0 +1,313 @@
+/**
+ * @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 decode_normal (vec2 enc);
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(srgb_to_linear(col.rgb), col.a);
+}
+
+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);
+
+ 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);
+ 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 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 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;
+}
+
+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);
+ 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)
+ {
+ 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;
+ //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));
+
+ 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..aa5e99a2f7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
@@ -0,0 +1,247 @@
+/**
+ * @file 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
+
+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;
+
+vec3 decode_normal (vec2 enc);
+
+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;
+
+ 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;
+}
+
+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;
+}
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..58f3f2f91e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
@@ -0,0 +1,308 @@
+/**
+ * @file 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
+
+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;
+
+vec3 decode_normal (vec2 enc);
+
+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;
+
+ 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;
+}
+
+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);
+
+ //frag_color.rgb = pos.xyz;
+ //frag_color.b = shadow;
+}
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/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
new file mode 100644
index 0000000000..fed3edf7de
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
@@ -0,0 +1,73 @@
+/**
+ * @file 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..52a7595379
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file 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..fee1a7f311
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
@@ -0,0 +1,148 @@
+/**
+ * @file 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();
+
+uniform sampler2D cloudMap;
+uniform vec4 gamma;
+uniform vec4 cloud_pos_density1;
+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 ssao_effect_mat;
+
+vec3 scaleFragSoftClip(vec3 light)
+{
+ //soft clip effect:
+ light = 1. - clamp(light, vec3(0.), vec3(1.));
+ light = 1. - pow(light, gamma.xxx);
+ return light;
+}
+
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
+{
+ light *= atten.r;
+ light += additive;
+ return (2.0 * light);
+}
+
+vec3 atmosLighting(vec3 light)
+{
+ return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
+}
+
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten) {
+
+ vec3 P = inPositionEye;
+
+ 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
+ atten = 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
+ additive =
+ 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
+ sunlit = vec3(sunlight * .5);
+ amblit = vec3(tmpAmbient * .25);
+ additive *= vec3(1.0 - temp1);
+}
+
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..3270c243a4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
@@ -0,0 +1,133 @@
+/**
+ * @file 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();
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+
+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 calcAtmospherics(vec3 inPositionEye) {
+
+ 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));
+}
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..e8e9c53c38
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
@@ -0,0 +1,74 @@
+/**
+ * @file 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 sampler2D cloudMap;
+uniform vec4 cloud_pos_density1;
+uniform int no_atmo;
+
+vec3 atmosFragTransport(vec3 light, vec3 atten, vec3 additive) {
+ if (no_atmo == 0)
+ {
+ light *= atten.r;
+ light += additive * 2.0;
+ }
+ return light;
+}
+
+vec3 fullbrightFragAtmosTransport(vec3 light, vec3 atten, vec3 additive) {
+ if (no_atmo)
+ {
+ return light;
+ }
+ loat brightness = dot(light.rgb, vec3(0.33333));
+ return mix(atmosFragTransport(light.rgb, atten, additive), light.rgb + additive.rgb, brightness * brightness);
+}
+
+vec3 fullbrightFragShinyAtmosTransport(vec3 light, vec3 atten, vec3 additive) {
+ if (no_atmo)
+ {
+ return light;
+ }
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return mix(atmosFragTransport(light.rgb, atten, additive), (light.rgb + additive.rgb) * (2.0 - brightness), brightness * brightness);
+}
+
+vec3 atmosTransport(vec3 light) {
+ return no_atmo ? light : atmosFragTransport(light, getAtmosAttenuation(), getAdditiveColor());
+}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ return no_atmo ? light : fullbrightFragAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor());
+}
+
+vec3 fullbrightShinyAtmosTransport(vec3 light) {
+ return no_atmo ? light : fullbrightFragShinyAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor());
+}
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/llagent.cpp b/indra/newview/llagent.cpp
index 9b8cc62aa8..5135d5072a 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -42,7 +42,6 @@
#include "llchicletbar.h"
#include "llconsole.h"
#include "lldonotdisturbnotificationstorage.h"
-#include "llenvmanager.h"
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterimcontainer.h"
@@ -382,6 +381,7 @@ LLAgent::LLAgent() :
mAgentOriginGlobal(),
mPositionGlobal(),
+ mLastTestGlobal(),
mDistanceTraveled(0.F),
mLastPositionGlobal(LLVector3d::zero),
@@ -1071,6 +1071,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);
+ }
}
//-----------------------------------------------------------------------------
@@ -1111,6 +1118,12 @@ const LLVector3 &LLAgent::getPositionAgent()
return mFrameAgent.getOrigin();
}
+boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot_type fn)
+{
+ return mOnPositionChanged.connect(fn);
+}
+
+
//-----------------------------------------------------------------------------
// getRegionsVisited()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index b1b39b637e..ad35c26dc6 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -189,6 +189,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,10 +198,16 @@ 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;
+ mutable LLVector3d mPositionGlobal;
+
+ position_signal_t mOnPositionChanged;
+ LLVector3d mLastTestGlobal;
//--------------------------------------------------------------------
// Velocity
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 170e4063a1..2b865a1ae2 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);
@@ -1540,7 +1538,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)
{
@@ -1563,13 +1560,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/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index c0f88ef704..e4a5c58c7b 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1026,14 +1026,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);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 189f7c1426..cb1a2e28fd 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -172,8 +172,6 @@
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
#include "llpostprocess.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "lldebugview.h"
#include "llconsole.h"
@@ -209,6 +207,7 @@
#include "llfloateroutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llsidepanelinventory.h"
+#include "llatmosphere.h"
// includes for idle() idleShutdown()
#include "llviewercontrol.h"
@@ -750,7 +749,9 @@ bool LLAppViewer::init()
// initialize LLWearableType translation bridge.
// Memory will be cleaned up in ::cleanupClass()
- LLWearableType::initClass(new LLUITranslationBridge());
+ LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>();
+ LLWearableType::initClass(trans);
+ LLSettingsType::initClass(trans);
// initialize SSE options
LLVector4a::initClass();
@@ -1631,6 +1632,8 @@ void LLAppViewer::flushVFSIO()
bool LLAppViewer::cleanup()
{
+ LLAtmosphere::cleanupClass();
+
//ditch LLVOAvatarSelf instance
gAgentAvatarp = NULL;
@@ -4883,7 +4886,6 @@ void LLAppViewer::idle()
//
// Update weather effects
//
- gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets
// Update wind vector
LLVector3 wind_position_region;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index e607b4a994..51d2d98485 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -390,8 +390,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/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp
index 803e2b2fb2..23d442f3b6 100644
--- a/indra/newview/lldaycyclemanager.cpp
+++ b/indra/newview/lldaycyclemanager.cpp
@@ -30,6 +30,9 @@
#include "lldiriterator.h"
+#include "llenvironment.h"
+#include "llsettingsdaycycle.h"
+
void LLDayCycleManager::getPresetNames(preset_name_list_t& names) const
{
names.clear();
diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h
index 04db9d5dac..810212c92a 100644
--- a/indra/newview/lldaycyclemanager.h
+++ b/indra/newview/lldaycyclemanager.h
@@ -30,7 +30,6 @@
#include <map>
#include <string>
-#include "llwldaycycle.h"
#include "llwlparammanager.h"
/**
@@ -46,14 +45,14 @@ class LLDayCycleManager : public LLSingleton<LLDayCycleManager>
public:
typedef std::list<std::string> preset_name_list_t;
- typedef std::map<std::string, LLWLDayCycle> dc_map_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, 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;
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/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 0873300cd2..7679d44826 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -117,6 +117,14 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
fullbright_shader->unbind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
@@ -260,17 +268,49 @@ void LLDrawPoolAlpha::render(S32 pass)
{
if (LLPipeline::sImpostorRender)
{
- fullbright_shader->bind();
+ fullbright_shader->bind();
fullbright_shader->setMinimumAlpha(0.5f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 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
{
fullbright_shader->bind();
fullbright_shader->setMinimumAlpha(0.f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
simple_shader->bind();
simple_shader->setMinimumAlpha(0.f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
else
@@ -610,7 +650,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
emissive_shader->bind();
-
+ if (LLPipeline::sRenderingHUDs)
+ {
+ emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
// do the actual drawing, again
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index ef69990170..2651e3531b 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -670,6 +670,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
@@ -720,6 +728,14 @@ 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()
@@ -763,6 +779,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
@@ -772,6 +796,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);
+ }
}
}
@@ -834,6 +866,14 @@ void LLDrawPoolAvatar::beginRiggedSimple()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -899,6 +939,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));
}
@@ -946,16 +996,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);
}
}
}
@@ -998,6 +1054,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);
}
}
@@ -1048,17 +1112,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);
}
}
}
@@ -1080,6 +1159,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()
@@ -1093,6 +1180,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);
}
@@ -1125,6 +1220,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);
@@ -1158,7 +1261,15 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
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();
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 7b9fd5c6c6..e27b6867b9 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -351,6 +351,14 @@ 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
{
@@ -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);
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index 59c3fbf7a1..e5ce0413b1 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -68,7 +68,7 @@ void LLDrawPoolGround::render(S32 pass)
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
+ LLGLSquashToFarClip far_clip(get_current_projection());
F32 water_height = gAgent.getRegion()->getWaterHeight();
gGL.pushMatrix();
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 63e96a93b5..113c198a9a 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -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);
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index bd180de6c6..bb50ad8e3e 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");
@@ -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);
@@ -170,6 +187,15 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
if (mVertexShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -263,6 +289,15 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
if (mVertexShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -296,6 +331,15 @@ void LLDrawPoolAlphaMask::render(S32 pass)
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);
@@ -336,6 +380,15 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
if (mVertexShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -369,12 +422,24 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
{
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();
@@ -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();
}
@@ -471,6 +555,14 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
{
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
{
@@ -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());
}
@@ -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);
+ }
}
}
@@ -621,6 +732,15 @@ void LLDrawPoolFullbright::render(S32 pass)
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);
@@ -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..2e4506ce47 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -102,7 +102,7 @@ void LLDrawPoolSky::render(S32 pass)
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
+ LLGLSquashToFarClip far_clip(get_current_projection());
LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index df06ad31e6..7a25e62651 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,42 +57,51 @@ 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);
+}
+LLDrawPoolWater::~LLDrawPoolWater()
+{
+}
- 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();
+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);
+}
- restoreGL();
+void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId);
+ mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
}
-LLDrawPoolWater::~LLDrawPoolWater()
+void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId)
{
+ 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);
}
//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());
+ }*/
}
LLDrawPool *LLDrawPoolWater::instancePool()
@@ -105,14 +113,7 @@ LLDrawPool *LLDrawPoolWater::instancePool()
void LLDrawPoolWater::prerender()
{
- mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
-
- // 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;
-
+ mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
}
S32 LLDrawPoolWater::getNumPasses()
@@ -203,10 +204,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 +267,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(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
@@ -362,8 +374,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,7 +471,7 @@ 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();
@@ -488,29 +498,39 @@ void LLDrawPoolWater::shade()
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);
+ 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_color = light_color + psky->getSunAmbient();
+ light_diffuse += psky->getSunDiffuse();
+ }
+
+ light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f);
+
+ if (moon_up)
+ {
+ LLColor3 moon_diffuse_color = psky->getMoonDiffuse();
+ light_color += moon_diffuse_color;
+ light_diffuse += moon_diffuse_color * 0.5f;
+
+ if (!sun_up)
+ {
+ 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;
@@ -518,20 +538,22 @@ void LLDrawPoolWater::shade()
light_exp *= 256.f;
light_exp = light_exp > 32.f ? light_exp : 32.f;
+ light_diffuse *= 6.f;
+
LLGLSLShader* shader;
- F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
+ F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight();
if (eyedepth < 0.f && LLPipeline::sWaterReflections)
{
- if (deferred_render)
- {
- shader = &gDeferredUnderWaterProgram;
- }
+ if (deferred_render)
+ {
+ shader = &gDeferredUnderWaterProgram;
+ }
else
- {
- shader = &gUnderWaterProgram;
- }
+ {
+ shader = &gUnderWaterProgram;
+ }
}
else if (deferred_render)
{
@@ -542,16 +564,18 @@ void LLDrawPoolWater::shade()
shader = &gWaterProgram;
}
+ shader->bind();
+
if (deferred_render)
{
- gPipeline.bindDeferredShader(*shader);
- }
- else
- {
- shader->bind();
+ 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);
+ }
}
- sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
+ sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
@@ -565,43 +589,48 @@ void LLDrawPoolWater::shade()
//bind normal map
S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
+ if (mWaterNormp[0])
+ {
+ gGL.getTexUnit(bumpTex)->bind(mWaterNormp[0]) ;
- // change mWaterNormp if needed
- if (mWaterNormp->getID() != param_mgr->getNormalMapID())
- {
- mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
+ if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+ {
+ mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
}
- 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);
- }
-
- 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);
+ if (mWaterNormp[1])
+ {
+ bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+
+ gGL.getTexUnit(bumpTex)->bind(mWaterNormp[1]) ;
+
+ if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+ {
+ mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
}
+
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getWaterFogColor().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getWaterFogDensity());
- stop_glerror();
-
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
if (mVertexShaderLevel == 1)
{
- sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
+ LLColor4 fog_color(pwater->getWaterFogColor(), 0.f);
+ fog_color[3] = pwater->getWaterFogDensity();
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
}
F32 screenRes[] =
@@ -615,25 +644,30 @@ void LLDrawPoolWater::shade()
S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
stop_glerror();
- light_dir.normVec();
- sLightDir = light_dir;
-
- light_diffuse *= 6.f;
-
//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
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 scaledAngle = 1.f - sunAngle;
@@ -648,12 +682,12 @@ void LLDrawPoolWater::shade()
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)
@@ -684,13 +718,16 @@ void LLDrawPoolWater::shade()
sNeedsDistortionUpdate = TRUE;
face->renderIndexed();
}
- else if (gGLManager.mHasDepthClamp || deferred_render)
- {
+ // using squash clip for deferred rendering makes the horizon lines match
+ // between ALM and non-ALM rendering (SL-1655), but introduces an ugly seem between
+ // near and far water(SL-9696)...we're going to live with the former and not cause the latter
+ else if (gGLManager.mHasDepthClamp || deferred_render)
+ {
face->renderIndexed();
}
else
{
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
+ LLGLSquashToFarClip far_clip(get_current_projection());
face->renderIndexed();
}
}
@@ -703,14 +740,7 @@ void LLDrawPoolWater::shade()
shader->disableTexture(LLShaderMgr::WATER_REFTEX);
shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
- if (deferred_render)
- {
- gPipeline.unbindDeferredShader(*shader);
- }
- else
- {
- shader->unbind();
- }
+ shader->unbind();
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..f14ac1f6d2 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -37,18 +37,17 @@ class LLWaterSurface;
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 LLVector3 sLightDir;
+// static LLColor4 sWaterFogColor;
static F32 sWaterFogEnd;
enum
@@ -83,6 +82,10 @@ public:
void renderReflection(LLFace* face);
void shade();
+ 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..455df837a9 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -33,7 +33,6 @@
#include "pipeline.h"
#include "llviewercamera.h"
#include "llimage.h"
-#include "llwlparammanager.h"
#include "llviewershadermgr.h"
#include "llglslshader.h"
#include "llsky.h"
@@ -42,53 +41,26 @@
#include "llface.h"
#include "llrender.h"
-LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
+#include "llenvironment.h"
+#include "llatmosphere.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 +79,69 @@ 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.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,30 +153,66 @@ 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.popMatrix();
}
-void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
- {
- LLGLDisable blend(GL_BLEND);
-
+ if (gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders() && gAtmosphere)
+ {
sky_shader->bind();
- /// Render the skydome
- renderDome(camHeightLocal, sky_shader);
+ // bind precomputed textures necessary for calculating sun and sky luminance
+ sky_shader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance());
+ sky_shader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering());
+ sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering());
+ sky_shader->bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance());
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ LLVector3 sun_dir = LLEnvironment::instance().getSunDirection();
+ LLVector3 moon_dir = LLEnvironment::instance().getMoonDirection();
+ F32 sunSize = (float)cosf(psky->getSunArcRadians());
+ sky_shader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize);
+ sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, sun_dir.mV);
+ sky_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, moon_dir.mV);
+
+ llassert(sky_shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX));
+
+ glh::matrix4f proj_mat = get_current_projection();
+ glh::matrix4f inv_proj = proj_mat.inverse();
+
+ sky_shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+
+ sky_shader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+
+ renderFsSky(camPosLocal, 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))
+ {
+ LLGLDisable blend(GL_BLEND);
+ sky_shader->bind();
+
+ /// Render the skydome
+ renderDome(origin, camHeightLocal, sky_shader);
+
+ sky_shader->unbind();
+ }
+}
+
void LLDrawPoolWLSky::renderStars(void) const
{
LLGLSPipelineSkyBox gls_sky;
@@ -190,25 +228,39 @@ void LLDrawPoolWLSky::renderStars(void) const
// *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.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 +272,8 @@ void LLDrawPoolWLSky::renderStars(void) const
gSky.mVOWLSkyp->drawStars();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
gGL.popMatrix();
if (LLGLSLShader::sNoFixedFunction)
@@ -233,19 +287,84 @@ void LLDrawPoolWLSky::renderStars(void) const
}
}
-void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderStarsDeferred(void) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull())
+ LLGLSPipelineSkyBox gls_sky;
+ LLGLEnable blend(GL_BLEND);
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+
+ F32 star_alpha = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 500.0f;
+
+ // If start_brightness is not set, exit
+ if(star_alpha < 0.001f)
+ {
+ LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
+ return;
+ }
+
+ gDeferredStarProgram.bind();
+
+ 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);
+ }
+
+ gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ if (LLPipeline::sRenderingWaterReflection)
+ {
+ star_alpha = 1.0f;
+ }
+ gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha);
+
+ sStarTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
+
+ 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();
+}
+
+void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const
+{
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
{
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
-
cloud_shader->bind();
+ cloud_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
+ cloud_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+ cloud_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
/// Render the skydome
- renderDome(camHeightLocal, cloud_shader);
+ renderDome(camPosLocal, camHeightLocal, cloud_shader);
cloud_shader->unbind();
}
@@ -257,49 +376,110 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
LLGLEnable blend_on(GL_BLEND);
gPipeline.disableLights();
-#if 0 // when we want to re-add a texture sun disc, here's where to do it.
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+ gGL.pushMatrix();
+ gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+
LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
- if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+ bool can_use_vertex_shaders = gPipeline.canUseVertexShaders();
+ bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders();
+
+
+ if (gSky.mVOSkyp->getSun().getDraw() && face && 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();
+ LLViewerTexture* tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
+ 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);
+
+ LLFacePool::LLOverrideFaceColor color_override(this, color);
+ face->renderIndexed();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ sun_shader->unbind();
+ }
+ }
}
-#endif
- LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
+ face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
- if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())
- {
- // *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();
- }
+ 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);
- LLFacePool::LLOverrideFaceColor color_override(this, color);
+ LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
- face->renderIndexed();
-
- if (gPipeline.canUseVertexShaders())
- {
- gHighlightProgram.unbind();
- }
- }
+ if (can_use_vertex_shaders && can_use_windlight_shaders)
+ {
+ 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);
+ }
+
+ moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
+ moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ LLFacePool::LLOverrideFaceColor color_override(this, color);
+ face->renderIndexed();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ moon_shader->unbind();
+ }
+ }
+
+ gGL.popMatrix();
}
void LLDrawPoolWLSky::renderDeferred(S32 pass)
@@ -310,43 +490,60 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
}
LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
+ const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
- LLGLSNoFog disableFog;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ LLGLSNoFog disableFog;
LLGLDisable clip(GL_CLIP_PLANE0);
gGL.setColorMask(true, false);
- 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]);
-
- 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());
-
- renderHeavenlyBodies();
+ LLGLSquashToFarClip far_clip(get_current_projection());
+
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
+ if (gPipeline.canUseWindLightShaders())
+ {
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+ if (gPipeline.useAdvancedAtmospherics())
+ {
+ //LLGLSquashToFarClip far_clip(get_current_projection());
+ renderSkyHazeDeferred(origin, camHeightLocal);
+ }
+ else
+ {
+ // Disable depth-test for sky, but re-enable depth writes for the cloud
+ // rendering below so the cloud shader can write out depth for the stars to test against
+ renderSkyHaze(origin, camHeightLocal);
+
+ }
+ renderHeavenlyBodies();
+ }
+ renderSkyClouds(origin, camHeightLocal);
+ }
+ gGL.setColorMask(true, true);
+}
- renderStars();
-
- gDeferredStarProgram.unbind();
+void LLDrawPoolWLSky::renderPostDeferred(S32 pass)
+{
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.popMatrix();
+ LLGLSNoFog disableFog;
+ LLGLDisable clip(GL_CLIP_PLANE0);
+ LLGLSquashToFarClip far_clip(get_current_projection());
- renderSkyClouds(camHeightLocal);
+ gGL.pushMatrix();
+ gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ gGL.setColorMask(true, false);
- gGL.setColorMask(true, true);
- //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ // would be nice to do this here, but would need said bodies
+ // to render at a realistic distance for depth-testing against the clouds...
+ //renderHeavenlyBodies();
+ renderStarsDeferred();
+ gGL.popMatrix();
+ gGL.setColorMask(true, true);
}
void LLDrawPoolWLSky::render(S32 pass)
@@ -357,34 +554,41 @@ void LLDrawPoolWLSky::render(S32 pass)
}
LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
+ const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
LLGLSNoFog disableFog;
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
LLGLDisable clip(GL_CLIP_PLANE0);
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
+ LLGLSquashToFarClip far_clip(get_current_projection());
- renderSkyHaze(camHeightLocal);
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.pushMatrix();
+ renderSkyHaze(origin, camHeightLocal);
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ bool use_advanced = gPipeline.useAdvancedAtmospherics();
+
+ if (!use_advanced)
+ {
+ gGL.pushMatrix();
+
+ // MAINT-9006 keep sun position consistent between ALM and non-ALM rendering
+ //gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
// *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.getTexUnit(1)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP));
renderHeavenlyBodies();
renderStars();
-
- gGL.popMatrix();
+ gGL.popMatrix();
+ }
- renderSkyClouds(camHeightLocal);
+ renderSkyClouds(origin, camHeightLocal);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -411,15 +615,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..309efdbc5b 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -34,10 +34,13 @@ class LLGLSLShader;
class LLDrawPoolWLSky : public LLDrawPool {
public:
- static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0;
- static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
+ static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX
+ | 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();
@@ -49,6 +52,12 @@ public:
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
+
+ /*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
+ /*virtual*/ void beginPostDeferredPass(S32 pass) {}
+ /*virtual*/ void endPostDeferredPass(S32 pass) {}
+ /*virtual*/ void renderPostDeferred(S32 pass);
+
/*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ void beginRenderPass( S32 pass );
/*virtual*/ void endRenderPass( S32 pass );
@@ -70,15 +79,16 @@ public:
static void cleanupGL();
static void restoreGL();
private:
- void renderDome(F32 camHeightLocal, LLGLSLShader * shader) const;
- void renderSkyHaze(F32 camHeightLocal) const;
+ void renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
+ void renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
+ void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+
+ void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+ void renderStarsDeferred(void) const;
+
void renderStars(void) const;
- void renderSkyClouds(F32 camHeightLocal) const;
+ void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const;
void renderHeavenlyBodies();
-
-private:
- static LLPointer<LLViewerTexture> sCloudNoiseTexture;
- static LLPointer<LLImageRaw> sCloudNoiseRawImage;
};
#endif // LL_DRAWPOOLWLSKY_H
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..5abb1b2e55
--- /dev/null
+++ b/indra/newview/llenvironment.cpp
@@ -0,0 +1,1884 @@
+/**
+ * @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"
+
+//=========================================================================
+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_DAYOFFSET("day_offset");
+ 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");
+
+ //---------------------------------------------------------------------
+ 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);
+ }
+
+ //---------------------------------------------------------------------
+ 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)
+ {
+ setTimeDeltaThreshold(updateThreshold);
+ // must happen prior to getBoundingEntries call...
+ mTrackNo = selectTrackNumber(trackno);
+
+ LLSettingsDay::TrackBound_t initial = getBoundingEntries(getAdjustedNow());
+
+ mInitial = (*initial.first).second;
+ mFinal = (*initial.second).second;
+ mBlendSpan = getSpanTime(initial);
+
+ 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);
+
+ setIgnoreTimeDeltaThreshold(true); // for the next span ignore the time delta threshold.
+ 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;
+ }
+
+ 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()
+ {
+ LLSettingsDay::TrackBound_t next = getBoundingEntries(getAdjustedNow());
+ LLSettingsBase::Seconds nextspan = getSpanTime(next);
+ reset((*next.first).second, (*next.second).second, nextspan);
+ }
+ };
+
+}
+
+//=========================================================================
+const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
+const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f);
+const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
+const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
+const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
+
+const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("4204c687-f9e4-4893-8c1b-46761c0d2021");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("07589e0e-8e2e-4864-8e58-07b516efd9c3");
+const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("8113ba47-3223-46ba-bae6-12c875091b32");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("90187088-d7f3-4656-8c27-8ba0e19e21e9");
+
+const S32 LLEnvironment::NO_TRACK(-1);
+
+const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
+
+//-------------------------------------------------------------------------
+LLEnvironment::LLEnvironment():
+ mCloudScrollDelta(),
+ mCloudScrollPaused(false),
+ mSelectedSky(),
+ mSelectedWater(),
+ mSelectedDay(),
+ mUserPrefs(),
+ mSelectedEnvironment(LLEnvironment::ENV_LOCAL),
+ mCurrentTrack(1)
+{
+}
+
+void LLEnvironment::initSingleton()
+{
+ LLSettingsSky::ptr_t p_default_sky = LLSettingsVOSky::buildDefaultSky();
+ LLSettingsWater::ptr_t p_default_water = LLSettingsVOWater::buildDefaultWater();
+
+ mCurrentEnvironment = std::make_shared<DayInstance>();
+ 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.
+ LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
+ gAgent.addRegionChangedCallback([this]() { requestRegion(); });
+
+ gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
+}
+
+LLEnvironment::~LLEnvironment()
+{
+}
+
+void LLEnvironment::loadPreferences()
+{
+ mUserPrefs.load();
+}
+
+void LLEnvironment::updatePreferences()
+{
+ /*NOOP for now. TODO record prefs and store.*/
+}
+
+bool LLEnvironment::canEdit() const
+{
+ return true;
+}
+
+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)
+ {
+ atmosphere::DensityProfileLayer layer;
+ LLSD& layerConfig = (*itf);
+ layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+ 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)
+ {
+ atmosphere::DensityProfileLayer layer;
+ LLSD& layerConfig = (*itf);
+ layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+ 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)
+ {
+ atmosphere::DensityProfileLayer layer;
+ LLSD& layerConfig = (*itf);
+ layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+ 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_OPTIONS);
+}
+
+bool LLEnvironment::canAgentUpdateRegionEnvironment() const
+{
+ if (gAgent.isGodlike())
+ return true;
+
+ return gAgent.getRegion()->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::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
+{
+ return gAgent.getRegion()->getWaterHeight();
+}
+
+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);
+}
+
+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 (!environment && create)
+ if (create)
+ {
+ environment = std::make_shared<DayInstance>();
+ mEnvironments[env] = environment;
+ }
+
+ return environment;
+}
+
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+ return;
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+
+ environment->clear();
+ environment->setDay(pday, daylength, dayoffset);
+ environment->setSkyTrack(mCurrentTrack);
+ environment->animate();
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env);
+}
+
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+ return;
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+
+ environment->clear();
+ environment->setSky((fixed.first) ? fixed.first : mEnvironments[ENV_DEFAULT]->getSky());
+ environment->setWater((fixed.second) ? fixed.second : mEnvironments[ENV_DEFAULT]->getWater());
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env);
+
+ /*TODO: readjust environment*/
+}
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings)
+{
+ 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());
+ if (environment)
+ {
+ fixedenv.second = environment->getWater();
+ }
+ setEnvironment(env, fixedenv);
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ fixedEnvironment_t fixedenv(LLSettingsSky::ptr_t(), std::static_pointer_cast<LLSettingsWater>(settings));
+ if (environment)
+ {
+ fixedenv.first = environment->getSky();
+ }
+ setEnvironment(env, fixedenv);
+ }
+}
+
+void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId)
+{
+ setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+}
+
+
+void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+{
+ LLSettingsVOBase::getSettingsAsset(assetId,
+ [this, env, daylength, dayoffset](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, status); });
+}
+
+void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 status)
+{
+ if (!settings || status)
+ {
+ LLSD args;
+ args["DESC"] = asset_id.asString();
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ return;
+ }
+
+ setEnvironment(env, settings);
+ updateEnvironment();
+}
+
+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;
+ }
+
+ mEnvironments[env].reset();
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env);
+
+ /*TODO: readjust environment*/
+}
+
+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." << 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." << 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." << 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)
+{
+ if (env == ENV_CURRENT)
+ {
+ fixedEnvironment_t fixed;
+ for (S32 idx = 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." << 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];
+}
+
+
+void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced)
+{
+ DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance();
+
+ if ((mCurrentEnvironment != pinstance) || forced)
+ {
+ DayInstance::ptr_t trans = std::make_shared<DayTransition>(
+ mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition);
+
+ trans->animate();
+
+ mCurrentEnvironment = trans;
+ }
+}
+
+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());
+
+ 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;
+ }
+
+}
+
+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;
+
+ bool found_in_settings = psetting->mSettings.has(it.first);
+ bool found_in_legacy_settings = !found_in_settings && psetting->mSettings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE].has(it.first);
+
+ if (!found_in_settings && !found_in_legacy_settings)
+ continue;
+
+ if (found_in_settings)
+ {
+ value = psetting->mSettings[it.first];
+ }
+ else if (found_in_legacy_settings)
+ {
+ value = psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE][it.first];
+ }
+
+ LLSD::Type setting_type = value.type();
+ stop_glerror();
+ switch (setting_type)
+ {
+ case LLSD::TypeInteger:
+ shader->uniform1i(it.second, value.asInteger());
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+ case LLSD::TypeReal:
+ shader->uniform1f(it.second, value.asReal());
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+
+ case LLSD::TypeBoolean:
+ shader->uniform1i(it.second, 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, 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);
+
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender)
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
+
+}
+
+void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader)
+{
+ if (gPipeline.canUseWindLightShaders())
+ {
+ updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater());
+ updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky());
+ }
+}
+
+void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo)
+{
+ 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(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+ updateEnvironment();
+ }
+ else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
+ || envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("LAPRAS") << "Invalid day cycle for region" << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+ updateEnvironment();
+ }
+ else
+ {
+ LL_INFOS("LAPRAS") << "Setting Region environment" << LL_ENDL;
+ setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset);
+ mTrackAltitudes = envinfo->mAltitudes;
+ }
+
+ LL_WARNS("LAPRAS") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL;
+ }
+ else
+ {
+ LLParcel *parcel = LLViewerParcelMgr::instance().getAgentParcel();
+ LL_WARNS("LAPRAS") << "Have parcel environment #" << envinfo->mParcelId << LL_ENDL;
+ if (parcel && (parcel->getLocalID() != parcel_id))
+ {
+ LL_WARNS("ENVIRONMENT") << "Requested parcel #" << parcel_id << " agent is on " << parcel->getLocalID() << LL_ENDL;
+ return;
+ }
+
+ if (!envinfo->mDayCycle)
+ {
+ LL_WARNS("LAPRAS") << "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("LAPRAS") << "Invalid day cycle for parcel #" << parcel_id << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ }
+ else
+ {
+ setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset);
+ }
+ }
+
+ updateEnvironment();
+}
+
+//=========================================================================
+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, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, pday, day_length, day_offset, cb);
+}
+
+void LLEnvironment::updateRegion(const LLUUID &asset_id, S32 day_length, S32 day_offset, 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, day_length, day_offset, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, psky, day_length, day_offset, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, pwater, day_length, day_offset, 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)
+ {
+ cb = [this](S32 pid, EnvironmentInfo::ptr_t envinfo)
+ {
+ recordEnvironment(pid, envinfo);
+ };
+ }
+
+ LLEnvironmentRequest::initiate(cb);
+ }
+ else if (cb)
+ cb(parcel_id, EnvironmentInfo::ptr_t());
+ return;
+ }
+
+ if (!cb)
+ {
+ cb = [this](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo); };
+ }
+
+ 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, S32 day_length, S32 day_offset, environment_apply_fn cb)
+{
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment",
+ [this, parcel_id, asset_id, day_length, day_offset, cb]() { coroUpdateEnvironment(parcel_id, NO_TRACK,
+ LLSettingsDay::ptr_t(), asset_id, day_length, day_offset, cb); });
+}
+
+void LLEnvironment::onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset)
+{
+ 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);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, environment_apply_fn cb)
+{
+ LLSettingsDay::ptr_t pday = createDayCycleFromEnvironment((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, psky);
+ updateParcel(parcel_id, pday, day_length, day_offset, cb);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, environment_apply_fn cb)
+{
+ LLSettingsDay::ptr_t pday = createDayCycleFromEnvironment((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, pwater);
+ updateParcel(parcel_id, pday, day_length, day_offset, cb);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, environment_apply_fn cb)
+{
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment",
+ [this, parcel_id, pday, day_length, day_offset, cb]() { coroUpdateEnvironment(parcel_id, NO_TRACK,
+ pday, LLUUID::null, day_length, day_offset, 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_WARNS("LAPRAS") << "Requesting for parcel_id=" << parcel_id << LL_ENDL;
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ std::stringstream query;
+
+ query << "?parcelid=" << parcel_id;
+ url += query.str();
+ }
+
+ LL_WARNS("LAPRAS") << "url=" << url << LL_ENDL;
+
+ LLSD result = httpAdapter->getAndSuspend(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)
+ {
+ LL_WARNS("WindlightCaps") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+
+// std::stringstream msg;
+// msg << status.toString() << " (Code " << status.toTerseString() << ")";
+// notify = LLSD::emptyMap();
+// notify["FAIL_REASON"] = msg.str();
+
+ }
+ 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::coroUpdateEnvironment(S32 parcel_id, S32 track_no, LLSettingsDay::ptr_t pday, LLUUID settings_asset, S32 day_length, S32 day_offset, 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;
+
+ if (day_length < 1)
+ {
+ day_length = getEnvironmentDayLength((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL).value();
+ if ((day_length < 1) && (parcel_id != INVALID_PARCEL_ID))
+ day_length = getEnvironmentDayLength(ENV_REGION).value();
+ }
+
+ if (day_offset < 1)
+ {
+ day_offset = getEnvironmentDayOffset((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL).value();
+ if ((day_offset < 1) && (parcel_id != INVALID_PARCEL_ID))
+ day_offset = getEnvironmentDayOffset(ENV_REGION).value();
+ }
+
+ 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 (day_length >= 0)
+ body[KEY_ENVIRONMENT][KEY_DAYLENGTH] = day_length;
+ if (day_offset >= 0)
+ body[KEY_ENVIRONMENT][KEY_DAYOFFSET] = day_offset;
+ }
+ if (pday)
+ body[KEY_ENVIRONMENT][KEY_DAYCYCLE] = pday->getSettings();
+ else if (!settings_asset.isNull())
+ body[KEY_ENVIRONMENT][KEY_DAYASSET] = settings_asset;
+
+
+ LL_WARNS("LAPRAS") << "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);
+ LL_WARNS("LAPRAS") << "success=" << result["success"] << LL_ENDL;
+ if ((!status) || !result["success"].asBoolean())
+ {
+ LL_WARNS("WindlightCaps") << "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);
+ LL_WARNS("LAPRAS") << "success=" << result["success"] << LL_ENDL;
+ if ((!status) || !result["success"].asBoolean())
+ {
+ LL_WARNS("WindlightCaps") << "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::UserPrefs::UserPrefs() :
+ mUseRegionSettings(true),
+ mUseDayCycle(true),
+ mPersistEnvironment(false),
+ mWaterPresetName(),
+ mSkyPresetName(),
+ mDayCycleName()
+{}
+
+
+void LLEnvironment::UserPrefs::load()
+{
+ mPersistEnvironment = gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin");
+
+ mWaterPresetName = gSavedSettings.getString("WaterPresetName");
+ mSkyPresetName = gSavedSettings.getString("SkyPresetName");
+ mDayCycleName = gSavedSettings.getString("DayCycleName");
+
+ mUseRegionSettings = mPersistEnvironment ? gSavedSettings.getBOOL("UseEnvironmentFromRegion") : true;
+ mUseDayCycle = mPersistEnvironment ? gSavedSettings.getBOOL("UseDayCycle") : true;
+}
+
+void LLEnvironment::UserPrefs::store()
+{
+ gSavedSettings.setBOOL("EnvironmentPersistAcrossLogin", mPersistEnvironment);
+ if (mPersistEnvironment)
+ {
+ gSavedSettings.setString("WaterPresetName", getWaterPresetName());
+ gSavedSettings.setString("SkyPresetName", getSkyPresetName());
+ gSavedSettings.setString("DayCycleName", getDayCycleName());
+
+ gSavedSettings.setBOOL("UseEnvironmentFromRegion", getUseRegionSettings());
+ gSavedSettings.setBOOL("UseDayCycle", getUseDayCycle());
+ }
+}
+
+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)
+{
+}
+
+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();
+ }
+
+ 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)
+{
+ std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(filename), true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPresetFile(name, path);
+ return water;
+}
+
+LLSettingsSky::ptr_t LLEnvironment::createSkyFromLegacyPreset(const std::string filename)
+{
+ std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(filename), true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPresetFile(name, path);
+ return sky;
+
+}
+
+LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromLegacyPreset(const std::string filename)
+{
+ std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(filename), true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPresetFile(name, path);
+ 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;
+
+ LL_WARNS("LAPRAS") << "Wants to switch to track #" << trackno << LL_ENDL;
+
+ 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);
+}
+
+
+//=========================================================================
+LLEnvironment::DayInstance::DayInstance() :
+ mDayCycle(),
+ mSky(),
+ mWater(),
+ mDayLength(LLSettingsDay::DEFAULT_DAYLENGTH),
+ mDayOffset(LLSettingsDay::DEFAULT_DAYOFFSET),
+ mBlenderSky(),
+ mBlenderWater(),
+ mInitialized(false),
+ mType(TYPE_INVALID),
+ mSkyTrack(1)
+{ }
+
+void LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+{
+ if (!mInitialized)
+ initialize();
+
+ if (mBlenderSky)
+ mBlenderSky->applyTimeDelta(delta);
+ if (mBlenderWater)
+ mBlenderWater->applyTimeDelta(delta);
+}
+
+void LLEnvironment::DayInstance::setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+{
+ if (mType == TYPE_FIXED)
+ LL_WARNS("ENVIRONMENT") << "Fixed day instance changed to Cycled" << LL_ENDL;
+ mType = TYPE_CYCLED;
+ mInitialized = false;
+
+ 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)
+{
+ if (mType == TYPE_CYCLED)
+ LL_WARNS("ENVIRONMENT") << "Cycled day instance changed to FIXED" << LL_ENDL;
+ mType = TYPE_FIXED;
+ 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)
+{
+ if (mType == TYPE_CYCLED)
+ LL_WARNS("ENVIRONMENT") << "Cycled day instance changed to FIXED" << LL_ENDL;
+ mType = TYPE_FIXED;
+ mInitialized = false;
+
+ mWater = pwater;
+ mWater->update();
+ mBlenderWater.reset();
+}
+
+void LLEnvironment::DayInstance::initialize()
+{
+ mInitialized = true;
+
+ if (!mWater)
+ mWater = LLSettingsVOWater::buildDefaultWater();
+ if (!mSky)
+ mSky = LLSettingsVOSky::buildDefaultSky();
+}
+
+void LLEnvironment::DayInstance::clear()
+{
+ mType = TYPE_INVALID;
+ 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::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;
+
+ 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);
+ }
+
+ // 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(),
+ mStartSky(skystart),
+ mStartWater(waterstart),
+ mNextInstance(end),
+ mTransitionTime(time)
+{
+
+}
+
+void LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+{
+ mNextInstance->applyTimeDelta(delta);
+ DayInstance::applyTimeDelta(delta);
+}
+
+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());
+ });
+}
+
+//=========================================================================
+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);
+}
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
new file mode 100644
index 0000000000..32a99c4286
--- /dev/null
+++ b/indra/newview/llenvironment.h
@@ -0,0 +1,402 @@
+/**
+ * @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(LLEnvironment);
+ LOG_CLASS(LLEnvironment);
+
+public:
+ static const F32Seconds TRANSITION_INSTANT;
+ static const F32Seconds TRANSITION_FAST;
+ static const F32Seconds TRANSITION_DEFAULT;
+ static const F32Seconds TRANSITION_SLOW;
+ static const F32Seconds TRANSITION_ALTITUDE;
+
+ static const LLUUID KNOWN_SKY_DEFAULT;
+ static const LLUUID KNOWN_WATER_DEFAULT;
+ static const LLUUID KNOWN_DAY_DEFAULT;
+ 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;
+
+ struct EnvironmentInfo
+ {
+ EnvironmentInfo();
+
+ typedef std::shared_ptr<EnvironmentInfo> ptr_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;
+
+ static ptr_t extract(LLSD);
+ static ptr_t extractLegacy(LLSD);
+ };
+
+ enum EnvSelection_t
+ {
+ ENV_EDIT = 0,
+ ENV_LOCAL,
+ ENV_PARCEL,
+ ENV_REGION,
+ ENV_DEFAULT,
+ ENV_END,
+ ENV_CURRENT = -1,
+ ENV_NONE = -2
+ };
+
+ typedef boost::signals2::connection connection_t;
+
+ class UserPrefs
+ {
+ friend class LLEnvironment;
+ public:
+ UserPrefs();
+
+ bool getUseRegionSettings() const { return mUseRegionSettings; }
+ bool getUseDayCycle() const { return mUseDayCycle; }
+ bool getUseFixedSky() const { return !getUseDayCycle(); }
+
+ std::string getWaterPresetName() const { return mWaterPresetName; }
+ std::string getSkyPresetName() const { return mSkyPresetName; }
+ std::string getDayCycleName() const { return mDayCycleName; }
+
+ void setUseRegionSettings(bool val);
+ void setUseWaterPreset(const std::string& name);
+ void setUseSkyPreset(const std::string& name);
+ void setUseDayCycle(const std::string& name);
+
+ private:
+ void load();
+ void store();
+
+ bool mUseRegionSettings;
+ bool mUseDayCycle;
+ bool mPersistEnvironment;
+ std::string mWaterPresetName;
+ std::string mSkyPresetName;
+ std::string mDayCycleName;
+ };
+
+ 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)> env_changed_signal_t;
+ typedef env_changed_signal_t::slot_type env_changed_fn;
+ typedef std::array<F32, 4> altitude_list_t;
+
+ virtual ~LLEnvironment();
+
+ void loadPreferences();
+ void updatePreferences();
+ const UserPrefs & getPreferences() const { return mUserPrefs; }
+
+ 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 { return mCurrentEnvironment->getSky(); }
+ LLSettingsWater::ptr_t getCurrentWater() const { return mCurrentEnvironment->getWater(); }
+
+ static void getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky);
+
+ void update(const LLViewerCamera * cam);
+
+ 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);
+ void setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed);
+ void setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed);
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t())); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed)); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw)); }
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId);
+
+ void clearEnvironment(EnvSelection_t env);
+ 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);
+ LLSettingsSky::ptr_t getEnvironmentFixedSky(EnvSelection_t env) { return getEnvironmentFixed(env).first; };
+ LLSettingsWater::ptr_t getEnvironmentFixedWater(EnvSelection_t env) { return getEnvironmentFixed(env).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;
+
+ // 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);
+ static LLSettingsSky::ptr_t createSkyFromLegacyPreset(const std::string filename);
+ static LLSettingsDay::ptr_t createDayCycleFromLegacyPreset(const std::string filename);
+
+ // 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);
+
+ //-------------------------------------------
+ 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, S32 day_length, S32 day_offset, environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, 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, S32 day_length, S32 day_offset, environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, 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; }
+
+protected:
+ virtual void initSingleton();
+
+private:
+ LLVector4 toCFR(const LLVector3 vec) const;
+ LLVector4 toLightNorm(const LLVector3 vec) const;
+
+ class DayInstance
+ {
+ public:
+ enum InstanceType_t
+ {
+ TYPE_INVALID,
+ TYPE_FIXED,
+ TYPE_CYCLED
+ };
+ typedef std::shared_ptr<DayInstance> ptr_t;
+
+ DayInstance();
+ virtual ~DayInstance() { };
+
+ virtual void applyTimeDelta(const LLSettingsBase::Seconds& delta);
+
+ void setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
+ void setSky(const LLSettingsSky::ptr_t &psky);
+ 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; }
+
+ virtual void animate();
+
+ void setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend);
+
+ protected:
+ LLSettingsDay::ptr_t mDayCycle;
+ LLSettingsSky::ptr_t mSky;
+ LLSettingsWater::ptr_t mWater;
+ S32 mSkyTrack;
+
+ InstanceType_t mType;
+ bool mInitialized;
+
+ LLSettingsDay::Seconds mDayLength;
+ LLSettingsDay::Seconds mDayOffset;
+ S32 mLastTrackAltitude;
+
+ LLSettingsBlender::ptr_t mBlenderSky;
+ LLSettingsBlender::ptr_t mBlenderWater;
+
+ LLSettingsBase::TrackPosition secondsToKeyframe(LLSettingsDay::Seconds seconds);
+ };
+ typedef std::array<DayInstance::ptr_t, ENV_END> InstanceArray_t;
+
+
+ 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 void applyTimeDelta(const LLSettingsBase::Seconds& delta);
+ virtual void animate();
+
+ protected:
+ LLSettingsSky::ptr_t mStartSky;
+ LLSettingsWater::ptr_t mStartWater;
+ DayInstance::ptr_t mNextInstance;
+ LLSettingsDay::Seconds mTransitionTime;
+ };
+
+ 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;
+
+ UserPrefs mUserPrefs;
+
+ S32 mCurrentTrack;
+ altitude_list_t mTrackAltitudes;
+
+ DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false);
+
+ DayInstance::ptr_t getSelectedEnvironmentInstance();
+
+
+ void updateCloudScroll();
+
+ void onParcelChange();
+
+ void coroRequestEnvironment(S32 parcel_id, environment_apply_fn apply);
+ void coroUpdateEnvironment(S32 parcel_id, S32 track_no, LLSettingsDay::ptr_t pday, LLUUID settings_asset, S32 day_length, S32 day_offset, 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);
+
+ void onAgentPositionHasChanged(const LLVector3 &localpos);
+
+ void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 status);
+ void onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset);
+
+};
+
+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..d5d8cda8ce 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)
{
@@ -148,6 +150,7 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
body["deny_age_unverified"] = getDenyAgeUnverified();
body["allow_voice_chat"] = getAllowVoiceChat();
body["override_public_access"] = getAllowAccessOverride();
+ body["override_environment"] = getAllowEnvironmentOverride();
body["invoice"] = LLFloaterRegionInfo::getLastInvoice();
@@ -222,6 +225,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/llface.cpp b/indra/newview/llface.cpp
index 06f64b7597..14b13c1f5f 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -306,6 +306,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);
@@ -1636,7 +1641,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);
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index ee545acb94..8531df8561 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -106,6 +106,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; }
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..4d3ebcda1e 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -241,7 +241,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;
}
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/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/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp
index 5c0991b0b3..4ddedbf7df 100644
--- a/indra/newview/llfloatereditdaycycle.cpp
+++ b/indra/newview/llfloatereditdaycycle.cpp
@@ -41,11 +41,11 @@
// newview
#include "llagent.h"
-#include "lldaycyclemanager.h"
-#include "llenvmanager.h"
#include "llregioninfomodel.h"
#include "llviewerregion.h"
-#include "llwlparammanager.h"
+
+#include "llenvironment.h"
+#include "lltrans.h"
const F32 LLFloaterEditDayCycle::sHoursPerDay = 24.0f;
@@ -114,7 +114,8 @@ 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
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ LLEnvironment::instance().updateEnvironment();
}
}
@@ -127,6 +128,7 @@ void LLFloaterEditDayCycle::draw()
void LLFloaterEditDayCycle::initCallbacks(void)
{
+#if 0
mDayCycleNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this), NULL);
mDayCyclesCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleSelected, this));
mDayCyclesCombo->setTextEntryCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this));
@@ -147,51 +149,55 @@ void LLFloaterEditDayCycle::initCallbacks(void)
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));
+#endif
}
void LLFloaterEditDayCycle::syncTimeSlider()
{
+#if 0
// set time
mTimeSlider->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay);
+#endif
}
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();
+// // 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()
{
+#if 0
LL_DEBUGS() << "Applying track (" << mSliderToKey.size() << ")" << LL_ENDL;
// if no keys, do nothing
@@ -220,10 +226,12 @@ void LLFloaterEditDayCycle::applyTrack()
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
+#endif
}
void LLFloaterEditDayCycle::refreshSkyPresetsList()
{
+#if 0
// 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;
@@ -269,10 +277,12 @@ void LLFloaterEditDayCycle::refreshSkyPresetsList()
// set defaults on combo boxes
mSkyPresetsCombo->selectFirstItem();
+#endif
}
void LLFloaterEditDayCycle::refreshDayCyclesList()
{
+#if 0
llassert(isNewDay() == false);
mDayCyclesCombo->removeall();
@@ -308,10 +318,12 @@ void LLFloaterEditDayCycle::refreshDayCyclesList()
}
mDayCyclesCombo->setLabel(getString("combo_label"));
+#endif
}
void LLFloaterEditDayCycle::onTimeSliderMoved()
{
+#if 0
/// get the slider value
F32 val = mTimeSlider->getCurSliderValue() / sHoursPerDay;
@@ -322,10 +334,12 @@ void LLFloaterEditDayCycle::onTimeSliderMoved()
// then call update once
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
+#endif
}
void LLFloaterEditDayCycle::onKeyTimeMoved()
{
+#if 0
if (mKeysSlider->getValue().size() == 0)
{
return;
@@ -351,10 +365,12 @@ void LLFloaterEditDayCycle::onKeyTimeMoved()
mTimeCtrl->setTime24(time24);
applyTrack();
+#endif
}
void LLFloaterEditDayCycle::onKeyTimeChanged()
{
+#if 0
// if no keys, skipped
if (mSliderToKey.size() == 0)
{
@@ -372,10 +388,12 @@ void LLFloaterEditDayCycle::onKeyTimeChanged()
mSliderToKey[cur_sldr].time = time;
applyTrack();
+#endif
}
void LLFloaterEditDayCycle::onKeyPresetChanged()
{
+#if 0
// do nothing if no sliders
if (mKeysSlider->getValue().size() == 0)
{
@@ -399,10 +417,12 @@ void LLFloaterEditDayCycle::onKeyPresetChanged()
// Apply changes to current day cycle.
applyTrack();
+#endif
}
void LLFloaterEditDayCycle::onAddKey()
{
+#if 0
llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
S32 max_sliders;
@@ -420,6 +440,7 @@ void LLFloaterEditDayCycle::onAddKey()
break;
}
+#if 0
if ((S32)mSliderToKey.size() >= max_sliders)
{
LLSD args;
@@ -428,6 +449,7 @@ void LLFloaterEditDayCycle::onAddKey()
LLNotificationsUtil::add("DayCycleTooManyKeyframes", args, LLSD(), LLNotificationFunctorRegistry::instance().DONOTHING);
return;
}
+#endif
// add the slider key
std::string key_val = mSkyPresetsCombo->getSelectedValue().asString();
@@ -439,8 +461,10 @@ void LLFloaterEditDayCycle::onAddKey()
// apply the change to current day cycles
applyTrack();
+#endif
}
+#if 0
void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe)
{
// make a slider
@@ -460,7 +484,9 @@ void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe)
llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
}
+#endif
+#if 0
LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle()
{
LLWLParamKey dc_key;
@@ -487,6 +513,7 @@ LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle()
return dc_key;
}
+#endif
bool LLFloaterEditDayCycle::isNewDay() const
{
@@ -495,6 +522,7 @@ bool LLFloaterEditDayCycle::isNewDay() const
void LLFloaterEditDayCycle::dumpTrack()
{
+#if 0
LL_DEBUGS("Windlight") << "Dumping day cycle" << LL_ENDL;
LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
@@ -505,6 +533,7 @@ void LLFloaterEditDayCycle::dumpTrack()
S32 m = (S32) ((time - h) * 60.0f);
LL_DEBUGS("Windlight") << llformat("(%.3f) %02d:%02d", time, h, m) << " => " << it->second.name << LL_ENDL;
}
+#endif
}
void LLFloaterEditDayCycle::enableEditing(bool enable)
@@ -518,6 +547,7 @@ void LLFloaterEditDayCycle::enableEditing(bool enable)
void LLFloaterEditDayCycle::reset()
{
+#if 0
// clear the slider
mKeysSlider->clear();
mSliderToKey.clear();
@@ -543,10 +573,12 @@ void LLFloaterEditDayCycle::reset()
// Disable controls until a day cycle to edit is selected.
enableEditing(false);
}
+#endif
}
void LLFloaterEditDayCycle::saveRegionDayCycle()
{
+#if 0
LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; // the day cycle being edited
@@ -570,6 +602,7 @@ void LLFloaterEditDayCycle::saveRegionDayCycle()
setApplyProgress(true);
#endif
+#endif
}
void LLFloaterEditDayCycle::setApplyProgress(bool started)
@@ -595,6 +628,7 @@ bool LLFloaterEditDayCycle::getApplyProgress() const
void LLFloaterEditDayCycle::onDeleteKey()
{
+#if 0
if (mSliderToKey.size() == 0)
{
return;
@@ -624,10 +658,12 @@ void LLFloaterEditDayCycle::onDeleteKey()
mTimeCtrl->setTime24(time24);
applyTrack();
+#endif
}
void LLFloaterEditDayCycle::onRegionSettingsChange()
{
+#if 0
LL_DEBUGS("Windlight") << "Region settings changed" << LL_ENDL;
if (getApplyProgress()) // our region settings have being applied
@@ -643,10 +679,12 @@ void LLFloaterEditDayCycle::onRegionSettingsChange()
closeFloater();
}
+#endif
}
void LLFloaterEditDayCycle::onRegionChange()
{
+#if 0
LL_DEBUGS("Windlight") << "Region changed" << LL_ENDL;
// If we're editing the region day cycle
@@ -654,6 +692,7 @@ void LLFloaterEditDayCycle::onRegionChange()
{
reset(); // undoes all unsaved changes
}
+#endif
}
void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success)
@@ -669,6 +708,7 @@ void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success)
void LLFloaterEditDayCycle::onRegionInfoUpdate()
{
+#if 0
LL_DEBUGS("Windlight") << "Region info updated" << LL_ENDL;
bool can_edit = true;
@@ -680,17 +720,22 @@ void LLFloaterEditDayCycle::onRegionInfoUpdate()
}
enableEditing(can_edit);
+#endif
}
void LLFloaterEditDayCycle::onDayCycleNameEdited()
{
+#if 0
// Disable saving a day cycle having empty name.
LLWLParamKey key = getSelectedDayCycle();
mSaveButton->setEnabled(!key.name.empty());
+#endif
}
void LLFloaterEditDayCycle::onDayCycleSelected()
{
+#if 0
+
LLSD day_data;
LLWLParamKey dc_key = getSelectedDayCycle();
bool can_edit = true;
@@ -722,12 +767,13 @@ void LLFloaterEditDayCycle::onDayCycleSelected()
F32 slider_time = mTimeSlider->getCurSliderValue() / sHoursPerDay;
LLWLParamManager::instance().applyDayCycleParams(day_data, dc_key.scope, slider_time);
loadTrack();
-
- enableEditing(can_edit);
+#endif
+ enableEditing(false);
}
void LLFloaterEditDayCycle::onBtnSave()
{
+#if 0
LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
LLWLParamKey selected_day = getSelectedDayCycle();
@@ -763,6 +809,7 @@ void LLFloaterEditDayCycle::onBtnSave()
// new preset, hence no confirmation needed
onSaveConfirmed();
}
+#endif
}
void LLFloaterEditDayCycle::onBtnCancel()
@@ -785,6 +832,7 @@ bool LLFloaterEditDayCycle::onSaveAnswer(const LLSD& notification, const LLSD& r
void LLFloaterEditDayCycle::onSaveConfirmed()
{
+#if 0
std::string name = getSelectedDayCycle().name;
// Save preset.
@@ -798,7 +846,7 @@ void LLFloaterEditDayCycle::onSaveConfirmed()
LL_DEBUGS("Windlight") << name << " is now the new preferred day cycle" << LL_ENDL;
LLEnvManagerNew::instance().setUseDayCycle(name);
}
-
+#endif
closeFloater();
}
diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h
index e6e4fe39c1..50d60a2b56 100644
--- a/indra/newview/llfloatereditdaycycle.h
+++ b/indra/newview/llfloatereditdaycycle.h
@@ -29,8 +29,6 @@
#include "llfloater.h"
-#include "llwlparammanager.h" // for LLWLParamKey
-
class LLCheckBoxCtrl;
class LLComboBox;
class LLLineEditor;
@@ -70,10 +68,10 @@ private:
void refreshDayCyclesList();
/// add a slider to the track
- void addSliderKey(F32 time, LLWLParamKey keyframe);
+// void addSliderKey(F32 time, LLWLParamKey keyframe);
void initCallbacks();
- LLWLParamKey getSelectedDayCycle();
+// LLWLParamKey getSelectedDayCycle();
bool isNewDay() const;
void dumpTrack();
void enableEditing(bool enable);
@@ -109,15 +107,15 @@ private:
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;
- };
+// 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;
@@ -131,7 +129,7 @@ private:
LLButton* mSaveButton;
// map of sliders to parameters
- std::map<std::string, SliderKey> mSliderToKey;
+// std::map<std::string, SliderKey> mSliderToKey;
};
#endif // LL_LLFLOATEREDITDAYCYCLE_H
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
new file mode 100644
index 0000000000..fac0ddc27b
--- /dev/null
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -0,0 +1,1594 @@
+/**
+ * @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 "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"
+
+// newview
+#include "llagent.h"
+#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 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 LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id");
+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");
+
+//=========================================================================
+LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
+ LLFloater(key),
+ mFlyoutControl(nullptr),
+ mDayLength(0),
+ mCurrentTrack(1),
+ mShiftCopyEnabled(false),
+ mTimeSlider(nullptr),
+ mFramesSlider(nullptr),
+ mCurrentTimeLabel(nullptr),
+ mImportButton(nullptr),
+ mInventoryId(),
+ mInventoryItem(nullptr),
+ mLoadFrame(nullptr),
+ mSkyBlender(),
+ mWaterBlender(),
+ mScratchSky(),
+ mScratchWater(),
+ mIsPlaying(false),
+ mIsDirty(false),
+ mCanCopy(false),
+ mCanMod(false),
+ mMakeNoTrans(false)
+{
+
+ 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);
+
+ 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) { onAddTrack(); });
+ mDeleteFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onRemoveTrack(); });
+ mImportButton->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonImport(); });
+ mLoadFrame->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonLoadFrame(); });
+
+ 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;
+
+ // Add or remove density tab as necessary
+ // Must be before operation on all tabs below
+ if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"))
+ {
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("panel_settings_sky_density"));
+ if (!panel)
+ {
+ panel = new LLPanelSettingsSkyDensityTab;
+ panel->buildFromFile("panel_settings_sky_density.xml");
+ tab_container->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false));
+ }
+ }
+ else
+ {
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("panel_settings_sky_density"));
+ if (panel)
+ {
+ tab_container->removeTabPanel(panel);
+ }
+ delete panel;
+ }
+
+ 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); });
+ }
+
+ //getChild<LLButton>("sky1_track", true)->setToggleState(true);
+
+ return TRUE;
+}
+
+void LLFloaterEditExtDayCycle::onOpen(const LLSD& key)
+{
+ 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
+ {
+ mCanCopy = true;
+ mCanMod = true;
+ mMakeNoTrans = false;
+ 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());
+ }
+
+ // 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 (int 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))
+ {
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_COMMIT);
+ }
+ else
+ {
+ mFlyoutControl->setShownBtnEnabled(false);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
+{
+ doCloseInventoryFloater(app_quitting);
+ // there's no point to change environment if we're quitting
+ // or if we already restored environment
+ stopPlay();
+ if (!app_quitting)
+ {
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_FAST);
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFocusReceived()
+{
+ if (isInVisibleChain())
+ {
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFocusLost()
+{
+}
+
+
+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);
+
+ 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());
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail && mCanCopy);
+ 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);
+ mLoadFrame->setEnabled(mCanMod);
+
+ LLFloater::refresh();
+}
+
+
+void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
+{
+ 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);
+ }
+
+ 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();
+ LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+/* virtual */
+BOOL LLFloaterEditExtDayCycle::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+ 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();
+ LLSettingsDay::ptr_t dayclone = mEditDay->buildClone(); // create a compressed copy
+
+ if (!dayclone)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unable to clone daycylce from editor." << LL_ENDL;
+ return;
+ }
+
+ 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::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string settings_name = response["message"].asString();
+ LLStringUtil::trim(settings_name);
+ doApplyCreateNewInventory(day, settings_name);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/)
+{
+ if (!app_quitting)
+ checkAndConfirmSettingsLoss([this](){ closeFloater(); });
+ else
+ closeFloater();
+}
+
+void LLFloaterEditExtDayCycle::onButtonImport()
+{
+ checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); });
+}
+
+void LLFloaterEditExtDayCycle::onButtonLoadFrame()
+{
+ LLUUID curassetId;
+
+ if (mCurrentEdit)
+ {
+ curassetId = mCurrentEdit->getAssetId();
+ }
+
+ doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, curassetId);
+}
+
+void LLFloaterEditExtDayCycle::onAddTrack()
+{
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ LLSettingsBase::ptr_t setting;
+ 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);
+ }
+
+ addSliderFrame(frame, setting);
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::onRemoveTrack()
+{
+ std::string sldr_key = mFramesSlider->getCurSlider();
+ if (sldr_key.empty())
+ {
+ return;
+ }
+ removeCurrentSliderFrame();
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data)
+{
+ 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();
+
+ F32 sliderpos(0.0);
+
+
+ if (curslider.empty())
+ {
+ S32 x(0), y(0);
+ LLUI::getMousePositionLocal(mFramesSlider, &x, &y);
+
+ sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+ }
+ else
+ {
+ 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;
+ }
+ }
+ else
+ {
+ if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos) && mCanMod)
+ {
+ (*it).second.mFrame = sliderpos;
+ }
+ else
+ {
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+
+ mShiftCopyEnabled = false;
+ }
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ onAddTrack();
+}
+
+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())
+ {
+ F32 sliderval = mFramesSlider->getSliderValue(slidername);
+
+ if (fabs(sliderval - sliderpos) > LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)
+ {
+ mFramesSlider->resetCurSlider();
+ }
+ }
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+
+ updateTabs();
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
+{
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+ selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+
+void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value)
+{
+ if (value)
+ setDirtyFlag();
+}
+
+void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb)
+{
+ if (isDirty())
+ {
+ LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType())
+ ("NAME", mEditDay->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 LLFloaterEditExtDayCycle::onTimeSliderCallback()
+{
+ stopPlay();
+ selectFrame(mTimeSlider->getCurSliderValue(), LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+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 (int 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();
+}
+
+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;
+ if (fabs(keyframe - frame) <= slop_factor)
+ {
+ 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->getChildView("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->getChildView("atmosphere_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("clouds_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("moon_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+
+ if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"))
+ {
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("panel_settings_sky_density"));
+ if (!panel)
+ {
+ panel = new LLPanelSettingsSkyDensityTab;
+ panel->buildFromFile("panel_settings_sky_density.xml");
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); });
+ tab_container->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false));
+ }
+ panel->setSky(std::static_pointer_cast<LLSettingsSky>(p_sky));
+ }
+ else
+ {
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("panel_settings_sky_density"));
+ if (panel)
+ {
+ tab_container->removeTabPanel(panel);
+ }
+ delete panel;
+ }
+
+}
+
+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...
+ //LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ //LLSettingsBase::ptr_t settings = mEditDay->getSettingsAtKeyframe(frame, mCurrentTrack);
+ //bool can_add = static_cast<bool>(settings);
+ //mAddFrameButton->setEnabled(can_add);
+ //mDeleteFrameButton->setEnabled(!can_add);
+ mAddFrameButton->setEnabled(mCanMod && mFramesSlider->canAddSliders());
+ mDeleteFrameButton->setEnabled(isRemovingFrameAllowed() && mCanMod);
+}
+
+void LLFloaterEditExtDayCycle::updateSlider()
+{
+ F32 frame_position = mTimeSlider->getCurSliderValue();
+ mFramesSlider->clear();
+ mSliderKeyMap.clear();
+
+ 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();
+ updateTabs();
+ }
+ 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(const F32 frame, 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();
+}
+
+//-------------------------------------------------------------------------
+
+LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSignal(LLFloaterEditExtDayCycle::edit_commit_signal_t::slot_type cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID &inventoryId)
+{
+ if (inventoryId.isNull())
+ {
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mCanCopy = true;
+ mCanMod = true;
+ mMakeNoTrans = false;
+ return;
+ }
+
+ mInventoryId = inventoryId;
+ LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
+ mInventoryItem = gInventory.getItem(mInventoryId);
+
+ if (!mInventoryItem)
+ {
+ LL_WARNS("ENVDAYEDIT") << "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("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
+
+ LLNotificationsUtil::add("UnableEditItem");
+ closeFloater();
+
+ mInventoryId.setNull();
+ mInventoryItem = nullptr;
+ return;
+ }
+
+ mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
+ mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
+
+ LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+ if ((mInventoryItem && mInventoryItem->getAssetUUID() != asset_id)
+ || (!mInventoryItem && LLSettingsDay::GetDefaultAssetId() != asset_id))
+ {
+ LL_WARNS("ENVDAYEDIT") << "Discarding obsolete asset callback" << LL_ENDL;
+ return;
+ }
+
+ if (!settings || status)
+ {
+ LLSD args;
+ args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ closeFloater();
+ return;
+ }
+
+ 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 (mInventoryItem)
+ settings->setName(mInventoryItem->getName());
+
+ setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+}
+
+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"
+ LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
+ bool canedit(false);
+
+ LLSettingsWater::ptr_t psettingW;
+ LLTabContainer * tabs = mWaterTabLayoutContainer->getChild<LLTabContainer>(TABS_WATER);
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ if (!mFramesSlider->getCurSlider().empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ LLSettingsDay::CycleTrack_t::value_type found = mEditDay->getSettingsNearKeyframe(frame, LLSettingsDay::TRACK_WATER, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+ psettingW = std::static_pointer_cast<LLSettingsWater>(found.second);
+ }
+ 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 (!mFramesSlider->getCurSlider().empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ LLSettingsDay::CycleTrack_t::value_type found = mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+ psettingS = std::static_pointer_cast<LLSettingsSky>(found.second);
+ }
+ mCurrentEdit = psettingS;
+ if (!psettingS)
+ {
+ canedit = false;
+ psettingS = mScratchSky;
+ }
+
+ getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingS = mScratchSky;
+ }
+ mEditSky = psettingS;
+
+ doCloseInventoryFloater();
+
+ 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->setSettings(settings);
+ panel->setCanChangeSettings(editable & mCanMod);
+ }
+ }
+}
+
+
+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::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name)
+{
+ // This method knows what sort of settings object to create.
+ LLUUID parent_id = mInventoryItem ? mInventoryItem->getParentUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+
+ LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+}
+
+void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day)
+{
+ if (mInventoryId.isNull())
+ LLSettingsVOBase::createInventoryItem(day, 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(day, mInventoryId,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
+}
+
+void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day)
+{
+ if (where == ACTION_APPLY_LOCAL)
+ {
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day);
+ }
+ else if (where == ACTION_APPLY_PARCEL)
+ {
+ LLParcelSelectionHandle handle(LLViewerParcelMgr::instance().getParcelSelection());
+ LLParcel *parcel(nullptr);
+
+ if (handle)
+ parcel = handle->getParcel();
+ if (!parcel || (parcel->getLocalID() == INVALID_PARCEL_ID))
+ parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
+ {
+ LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL;
+ LLNotificationsUtil::add("WLParcelApplyFail");
+ return;
+ }
+
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), -1, -1);
+ }
+ else
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1);
+ }
+ }
+ else if (where == ACTION_APPLY_REGION)
+ {
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), -1, -1);
+ }
+ else
+ {
+ LLEnvironment::instance().updateRegion(day, -1, -1);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL;
+ return;
+ }
+
+}
+
+void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
+{
+ if (!mCommitSignal.empty())
+ {
+ mCommitSignal(day);
+
+ closeFloater();
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
+{
+ if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)
+ {
+ return (mSliderKeyMap.size() > 1);
+ }
+ else
+ {
+ return (mSliderKeyMap.size() > 0);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_INFOS("ENVDAYEDIT") << "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;
+ }
+
+ if (mInventoryItem)
+ {
+ LLPermissions perms = mInventoryItem->getPermissions();
+
+ LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+ if (created_item)
+ {
+ created_item->setPermissions(perms);
+ created_item->updateServer(false);
+ }
+ }
+
+ clearDirtyFlag();
+ setFocus(TRUE); // Call back the focus...
+ loadInventoryItem(inventory_id);
+}
+
+void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_WARNS("ENVDAYEDIT") << "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 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)
+{
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LL_WARNS("LAPRAS") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsDay::ptr_t legacyday = LLEnvironment::createDayCycleFromLegacyPreset(filename);
+
+ if (!legacyday)
+ {
+ LLSD args(LLSDMap("FILE", filename));
+ LLNotificationsUtil::add("WLImportFail", args);
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ mCurrentTrack = 1;
+ setDirtyFlag();
+ setEditDayCycle(legacyday);
+}
+
+bool LLFloaterEditExtDayCycle::canUseInventory() const
+{
+ return LLEnvironment::instance().isInventoryEnabled();
+}
+
+bool LLFloaterEditExtDayCycle::canApplyRegion() const
+{
+ return gAgent.canManageEstate();
+}
+
+bool LLFloaterEditExtDayCycle::canApplyParcel() const
+{
+ LLParcelSelectionHandle handle(LLViewerParcelMgr::instance().getParcelSelection());
+ LLParcel *parcel(nullptr);
+
+ if (handle)
+ parcel = handle->getParcel();
+ if (!parcel)
+ parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if (!parcel)
+ return false;
+
+ return parcel->allowTerraformBy(gAgent.getID()) &&
+ LLEnvironment::instance().isExtendedEnvironmentEnabled();
+}
+
+void LLFloaterEditExtDayCycle::startPlay()
+{
+ doCloseInventoryFloater();
+
+ 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)
+{
+ 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();
+
+}
+
+
+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::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID currasset)
+{
+// LLUI::sWindow->setCursor(UI_CURSOR_WAIT);
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null, "SELECT SETTINGS");
+
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data.asUUID()); });
+ }
+
+ picker->setSettingsFilter(type);
+ picker->setSettingsAssetId(currasset);
+ picker->openFloater();
+ picker->setFocus(TRUE);
+}
+
+void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting)
+{
+ LLFloater* floaterp = mInventoryFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID asset_id)
+{
+ LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
+ S32 track = mCurrentTrack;
+
+ LLSettingsVOBase::getSettingsAsset(asset_id,
+ [this, track, frame](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoadedForFrame(asset_id, settings, status, track, frame); });
+}
+
+void LLFloaterEditExtDayCycle::onAssetLoadedForFrame(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 track, LLSettingsBase::TrackPosition frame)
+{
+ std::function<void()> cb = [this, settings, frame, track]()
+ {
+ mEditDay->setSettingsAtKeyframe(settings, frame, track);
+ reblendSettings();
+ synchronizeTabs();
+ };
+
+ if (!settings || status)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Could not load asset " << asset_id << " into frame. status=" << status << LL_ENDL;
+ return;
+ }
+
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
+ LLInventoryItem *inv_item(nullptr);
+
+ if (picker)
+ {
+ inv_item = picker->findItem(asset_id, false, false);
+ }
+
+ if (inv_item)
+ {
+ if (mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ if (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ 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)
+ {
+ mMakeNoTrans = true;
+ 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..1e40a9dc6e
--- /dev/null
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -0,0 +1,228 @@
+/**
+ * @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"
+
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLFlyoutComboBtnCtrl;
+class LLLineEditor;
+class LLMultiSliderCtrl;
+class LLTextBox;
+class LLTimeCtrl;
+class LLTabContainer;
+
+class LLInventoryItem;
+
+typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t;
+
+/**
+ * Floater for creating or editing a day cycle.
+ */
+class LLFloaterEditExtDayCycle : public LLFloater
+{
+ LOG_CLASS(LLFloaterEditExtDayCycle);
+
+public:
+ static const std::string KEY_INVENTORY_ID;
+ 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();
+
+ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override;
+
+ BOOL isDirty() const override { return getIsDirty(); }
+
+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 onAddTrack();
+ void onRemoveTrack();
+ void onCommitName(class LLLineEditor* caller, void* user_data);
+ void onTrackSelectionCallback(const LLSD& user_data);
+ void onPlayActionCallback(const LLSD& user_data);
+ void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day);
+ // 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 onPanelDirtyFlagChanged(bool);
+
+ void checkAndConfirmSettingsLoss(on_confirm_fn cb);
+
+ 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 updateSlider(); //generate sliders from current track
+ void updateTimeAndLabel();
+ void addSliderFrame(const F32 frame, LLSettingsBase::ptr_t &setting, bool update_ui = true);
+ void removeCurrentSliderFrame();
+
+ void loadInventoryItem(const LLUUID &inventoryId);
+ void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
+
+ void doImportFromDisk();
+ void loadSettingFromFile(const std::vector<std::string>& filenames);
+ void doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name);
+ void doApplyUpdateInventory(const LLSettingsDay::ptr_t &day);
+ void doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day);
+ void doApplyCommit(LLSettingsDay::ptr_t day);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+ void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+ void doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID currasset);
+ void doCloseInventoryFloater(bool quitting = false);
+ void onPickerCommitSetting(LLUUID asset_id);
+ void onAssetLoadedForFrame(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 track, LLSettingsBase::TrackPosition frame);
+
+ bool canUseInventory() const;
+ bool canApplyRegion() const;
+ bool canApplyParcel() const;
+
+ void updateEditEnvironment();
+ 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();
+
+ bool isRemovingFrameAllowed();
+
+ LLSettingsDay::ptr_t mEditDay; // edited copy
+ LLSettingsDay::Seconds mDayLength;
+ U32 mCurrentTrack;
+ std::string mLastFrameSlider;
+ bool mShiftCopyEnabled;
+
+ LLButton* mAddFrameButton;
+ LLButton* mDeleteFrameButton;
+ LLButton* mImportButton;
+ LLButton* mLoadFrame;
+ LLMultiSliderCtrl* mTimeSlider;
+ LLMultiSliderCtrl* mFramesSlider;
+ LLView* mSkyTabLayoutContainer;
+ LLView* mWaterTabLayoutContainer;
+ LLTextBox* mCurrentTimeLabel;
+ LLUUID mInventoryId;
+ LLInventoryItem * mInventoryItem;
+ LLFlyoutComboBtnCtrl * mFlyoutControl;
+
+ LLHandle<LLFloater> mInventoryFloater;
+
+ 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;
+ bool mIsDirty;
+ bool mCanCopy;
+ bool mCanMod;
+ bool mMakeNoTrans;
+
+ 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/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/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
new file mode 100644
index 0000000000..b9ea044a06
--- /dev/null
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -0,0 +1,751 @@
+/**
+ * @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 "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 "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");
+}
+
+//=========================================================================
+const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id");
+
+
+//=========================================================================
+LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) :
+ LLFloater(key),
+ mFlyoutControl(nullptr),
+ mInventoryId(),
+ mInventoryItem(nullptr),
+ mIsDirty(false),
+ mCanCopy(false),
+ mCanMod(false)
+{
+}
+
+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_FAST);
+
+}
+
+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::onFocusReceived()
+{
+ if (isInVisibleChain())
+ {
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+ }
+}
+
+void LLFloaterFixedEnvironment::onFocusLost()
+{
+}
+
+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->refresh();
+ panel->setCanChangeSettings(mCanMod);
+ }
+ }
+}
+
+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, "SELECT SETTINGS");
+
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data.asUUID()); });
+ }
+
+ return picker;
+}
+
+void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID &inventoryId)
+{
+ if (inventoryId.isNull())
+ {
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mCanMod = true;
+ mCanCopy = 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;
+ }
+
+ mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
+ mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
+
+ LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+
+void LLFloaterFixedEnvironment::checkAndConfirmSettingsLoss(LLFloaterFixedEnvironment::on_confirm_fn cb)
+{
+ if (isDirty())
+ {
+ LLSD args(LLSDMap("TYPE", mSettings->getSettingsType())
+ ("NAME", mSettings->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 LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID asset_id)
+{
+ mInventoryItem = NULL;
+ mInventoryId.setNull();
+ if (!mInventoryFloater.isDead())
+ {
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
+ if (picker)
+ {
+ mInventoryId = picker->findItemID(asset_id, false);
+ mInventoryItem = gInventory.getItem(mInventoryId);
+ }
+ }
+
+ LLSettingsVOBase::getSettingsAsset(asset_id,
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+ if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id)
+ {
+ LL_WARNS("ENVIRONMENT") << "Discarding obsolete asset callback" << LL_ENDL;
+ return;
+ }
+
+ if (!settings || status)
+ {
+ LLSD args;
+ args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ closeFloater();
+ return;
+ }
+
+ mSettings = settings;
+ if (mInventoryItem)
+ mSettings->setName(mInventoryItem->getName());
+
+ updateEditEnvironment();
+ syncronizeTabs();
+ refresh();
+}
+
+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();
+
+ if (ctrl_action == ACTION_SAVE)
+ {
+ doApplyUpdateInventory();
+ }
+ else if (ctrl_action == ACTION_SAVEAS)
+ {
+ LLSD args;
+ args["DESC"] = mSettings->getName();
+ LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterFixedEnvironment::onSaveAsCommit, this, _1, _2));
+ }
+ else if ((ctrl_action == ACTION_APPLY_LOCAL) ||
+ (ctrl_action == ACTION_APPLY_PARCEL) ||
+ (ctrl_action == ACTION_APPLY_REGION))
+ {
+ doApplyEnvironment(ctrl_action);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL;
+ }
+}
+
+void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string settings_name = response["message"].asString();
+ LLStringUtil::trim(settings_name);
+ doApplyCreateNewInventory(settings_name);
+ }
+}
+
+void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ checkAndConfirmSettingsLoss([this](){ closeFloater(); });
+ else
+ closeFloater();
+}
+
+void LLFloaterFixedEnvironment::onButtonLoad()
+{
+ checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); });
+}
+
+void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name)
+{
+ LLUUID parent_id = mInventoryItem ? mInventoryItem->getParentUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ // This method knows what sort of settings object to create.
+ LLSettingsVOBase::createInventoryItem(mSettings, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+}
+
+void LLFloaterFixedEnvironment::doApplyUpdateInventory()
+{
+ LL_WARNS("LAPRAS") << "Update inventory for " << mInventoryId << LL_ENDL;
+ if (mInventoryId.isNull())
+ {
+ LL_WARNS("LAPRAS") << "Inventory ID is NULL. Creating New!!!" << LL_ENDL;
+ LLSettingsVOBase::createInventoryItem(mSettings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+ else
+ {
+ LL_WARNS("LAPRAS") << "Updating inventory ID " << mInventoryId << LL_ENDL;
+ LLSettingsVOBase::updateInventoryItem(mSettings, mInventoryId,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
+ }
+}
+
+void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where)
+{
+ if (where == ACTION_APPLY_LOCAL)
+ {
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mSettings);
+ }
+ else if (where == ACTION_APPLY_PARCEL)
+ {
+ LLParcelSelectionHandle handle(LLViewerParcelMgr::instance().getParcelSelection());
+ LLParcel *parcel(nullptr);
+
+ if (handle)
+ parcel = handle->getParcel();
+ if (!parcel)
+ parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ 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(), -1, -1);
+ }
+ else if (mSettings->getSettingsType() == "sky")
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(mSettings), -1, -1);
+ }
+ else if (mSettings->getSettingsType() == "water")
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(mSettings), -1, -1);
+ }
+ }
+ else if (where == ACTION_APPLY_REGION)
+ {
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), -1, -1);
+ }
+ else if (mSettings->getSettingsType() == "sky")
+ {
+ LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(mSettings), -1, -1);
+ }
+ else if (mSettings->getSettingsType() == "water")
+ {
+ LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(mSettings), -1, -1);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL;
+ return;
+ }
+
+}
+
+void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting)
+{
+ LLFloater* floaterp = mInventoryFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+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;
+ }
+
+ if (mInventoryItem)
+ {
+ LLPermissions perms = mInventoryItem->getPermissions();
+
+ LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+ if (created_item)
+ {
+ created_item->setPermissions(perms);
+ created_item->updateServer(false);
+ }
+ }
+ clearDirtyFlag();
+ setFocus(TRUE); // Call back the focus...
+ loadInventoryItem(inventory_id);
+}
+
+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);
+}
+
+void LLFloaterFixedEnvironment::onPanelDirtyFlagChanged(bool value)
+{
+ if (value)
+ setDirtyFlag();
+}
+
+//-------------------------------------------------------------------------
+bool LLFloaterFixedEnvironment::canUseInventory() const
+{
+ return LLEnvironment::instance().isInventoryEnabled();
+}
+
+bool LLFloaterFixedEnvironment::canApplyRegion() const
+{
+ return gAgent.canManageEstate();
+}
+
+bool LLFloaterFixedEnvironment::canApplyParcel() const
+{
+ LLParcelSelectionHandle handle(LLViewerParcelMgr::instance().getParcelSelection());
+ LLParcel *parcel(nullptr);
+
+ if (handle)
+ parcel = handle->getParcel();
+ if (!parcel)
+ parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if (!parcel)
+ return false;
+
+ return parcel->allowModifyBy(gAgent.getID(), gAgent.getGroupID()) &&
+ LLEnvironment::instance().isExtendedEnvironmentEnabled();
+}
+
+//=========================================================================
+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)
+{
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LL_WARNS("LAPRAS") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsWater::ptr_t legacywater = LLEnvironment::createWaterFromLegacyPreset(filename);
+
+ if (!legacywater)
+ {
+ LLSD args(LLSDMap("FILE", filename));
+ LLNotificationsUtil::add("WLImportFail", args);
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ setDirtyFlag();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater);
+ setEditSettings(legacywater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, 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));
+
+ if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"))
+ {
+ panel = new LLPanelSettingsSkyDensityTab;
+ panel->buildFromFile("panel_settings_sky_density.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)");
+
+ // TODO: Should we grab water and keep it around for reference?
+ }
+
+ LLFloaterFixedEnvironment::onOpen(key);
+}
+
+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];
+
+ LL_WARNS("LAPRAS") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsSky::ptr_t legacysky = LLEnvironment::createSkyFromLegacyPreset(filename);
+
+ if (!legacysky)
+ {
+ LLSD args(LLSDMap("FILE", filename));
+ LLNotificationsUtil::add("WLImportFail", args);
+
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ clearDirtyFlag();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky);
+ setEditSettings(legacysky);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
+}
+
+//=========================================================================
+
+void LLSettingsEditPanel::setCanChangeSettings(bool enabled)
+{
+ setEnabled(enabled);
+ setAllChildrenEnabled(enabled);
+}
diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h
new file mode 100644
index 0000000000..d235491fd9
--- /dev/null
+++ b/indra/newview/llfloaterfixedenvironment.h
@@ -0,0 +1,199 @@
+/**
+ * @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 "llfloater.h"
+#include "llsettingsbase.h"
+#include "llflyoutcombobtn.h"
+#include "llinventory.h"
+
+#include "boost/signals2.hpp"
+
+class LLTabContainer;
+class LLButton;
+class LLLineEditor;
+class LLFloaterSettingsPicker;
+
+/**
+ * Floater container for creating and editing fixed environment settings.
+ */
+class LLFloaterFixedEnvironment : public LLFloater
+{
+ LOG_CLASS(LLFloaterFixedEnvironment);
+
+public:
+ static const std::string KEY_INVENTORY_ID;
+
+ LLFloaterFixedEnvironment(const LLSD &key);
+ ~LLFloaterFixedEnvironment();
+
+ 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;
+
+ void setEditSettings(const LLSettingsBase::ptr_t &settings) { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); }
+ LLSettingsBase::ptr_t getEditSettings() const { return mSettings; }
+
+ virtual BOOL isDirty() const override { return getIsDirty(); }
+
+protected:
+ typedef std::function<void()> on_confirm_fn;
+
+ virtual void updateEditEnvironment() = 0;
+ virtual void refresh() override;
+ virtual void syncronizeTabs();
+
+ LLFloaterSettingsPicker *getSettingsPicker();
+
+ void loadInventoryItem(const LLUUID &inventoryId);
+
+ void checkAndConfirmSettingsLoss(on_confirm_fn cb);
+
+ LLTabContainer * mTab;
+ LLLineEditor * mTxtName;
+
+ LLSettingsBase::ptr_t mSettings;
+
+ virtual void doImportFromDisk() = 0;
+ virtual void doApplyCreateNewInventory(std::string settings_name);
+ virtual void doApplyUpdateInventory();
+ virtual void doApplyEnvironment(const std::string &where);
+ void doCloseInventoryFloater(bool quitting = false);
+
+ bool canUseInventory() const;
+ bool canApplyRegion() const;
+ bool canApplyParcel() const;
+
+ LLFlyoutComboBtnCtrl * mFlyoutControl;
+
+ LLUUID mInventoryId;
+ LLInventoryItem * mInventoryItem;
+ LLHandle<LLFloater> mInventoryFloater;
+ bool mCanCopy;
+ bool mCanMod;
+
+ 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();
+
+ void doSelectFromInventory();
+ void onPanelDirtyFlagChanged(bool);
+
+ virtual void onClickCloseBtn(bool app_quitting = false) override;
+ void onSaveAsCommit(const LLSD& notification, const LLSD& response);
+
+private:
+ void onNameChanged(const std::string &name);
+
+ void onButtonImport();
+ void onButtonApply(LLUICtrl *ctrl, const LLSD &data);
+ void onButtonLoad();
+
+ void onPickerCommitSetting(LLUUID asset_id);
+ void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
+
+ bool mIsDirty;
+};
+
+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;
+
+protected:
+ virtual void updateEditEnvironment() override;
+
+ virtual void doImportFromDisk() override;
+ void loadSkySettingFromFile(const std::vector<std::string>& filenames);
+
+private:
+};
+
+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); }
+
+ virtual void setCanChangeSettings(bool flag);
+
+ inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb) { return mOnDirtyChanged.connect(cb); }
+
+
+protected:
+ LLSettingsEditPanel() :
+ LLPanel(),
+ mIsDirty(false),
+ mOnDirtyChanged()
+ {}
+
+private:
+ bool mIsDirty;
+
+ on_dirty_charged_sg mOnDirtyChanged;
+};
+
+#endif // LL_FLOATERFIXEDENVIRONMENT_H
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index b840d37c4d..57c010502e 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -470,7 +470,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/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 88b3fb7b96..1147f54853 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -78,9 +78,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;
@@ -138,6 +140,33 @@ protected:
LLPanelExperienceListEditor* mBlocked;
};
+
+class LLPanelLandEnvironment
+ : public LLPanelEnvironmentInfo
+{
+public:
+ LLPanelLandEnvironment(LLSafeHandle<LLParcelSelection>& parcelp);
+
+ virtual bool isRegion() const override { return 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]
@@ -277,6 +306,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 );
@@ -318,6 +348,7 @@ void LLFloaterLand::refresh()
mPanelAccess->refresh();
mPanelCovenant->refresh();
mPanelExperiences->refresh();
+ mPanelEnvironment->refresh();
}
@@ -386,6 +417,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
@@ -3211,3 +3250,126 @@ 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>(RDO_USEDEFAULT)->setLabelArg("[USEDEFAULT]", getString(STR_LABEL_USEREGION));
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setVisible(FALSE);
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(FALSE);
+ return TRUE;
+}
+
+void LLPanelLandEnvironment::refresh()
+{
+ if (gDisconnected)
+ return;
+
+ if (!isSameRegion())
+ {
+ setCrossRegion(true);
+ mCurrentEnvironment.reset();
+ mLastParcelId = INVALID_PARCEL_ID;
+ setControlsEnabled(false);
+ return;
+ }
+
+ if (mLastParcelId != getParcelId())
+ {
+ mCurrentEnvironment.reset();
+ }
+
+ if (!mCurrentEnvironment)
+ {
+ refreshFromSource();
+ return;
+ }
+
+ LLPanelEnvironmentInfo::refresh();
+}
+
+void LLPanelLandEnvironment::refreshFromSource()
+{
+ LLParcel *parcel = getParcel();
+
+ if (!LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ {
+ setNoEnvironmentSupport(true);
+ setControlsEnabled(false);
+ return;
+ }
+ setNoEnvironmentSupport(false);
+
+ if (!parcel)
+ {
+ setNoSelection(true);
+ setControlsEnabled(false);
+ return;
+ }
+
+ setNoSelection(false);
+ if (isSameRegion())
+ {
+ setCrossRegion(false);
+
+ LLHandle<LLPanel> that_h = getHandle();
+
+ 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;
+ }
+ 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);
+}
+
+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 0540ddb880..0eea46bc5a 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,7 +104,8 @@ protected:
static void* createPanelLandMedia(void* data);
static void* createPanelLandAccess(void* data);
static void* createPanelLandExperiences(void* data);
- static void* createPanelLandBan(void* data);
+ static void* createPanelLandEnvironment(void* data);
+ static void* createPanelLandBan(void* data);
protected:
@@ -119,6 +121,7 @@ protected:
LLPanelLandAccess* mPanelAccess;
LLPanelLandCovenant* mPanelCovenant;
LLPanelLandExperiences* mPanelExperiences;
+ LLPanelLandEnvironment *mPanelEnvironment;
LLSafeHandle<LLParcelSelection> mParcel;
diff --git a/indra/newview/llfloatermyenvironment.cpp b/indra/newview/llfloatermyenvironment.cpp
new file mode 100644
index 0000000000..6dcff7c264
--- /dev/null
+++ b/indra/newview/llfloatermyenvironment.cpp
@@ -0,0 +1,494 @@
+/**
+ * @file llfloatergesture.cpp
+ * @brief Read-only list of gestures from your inventory.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatermyenvironment.h"
+
+#include "llinventory.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+#include "llclipboard.h"
+
+#include "llagent.h"
+#include "llclipboard.h"
+#include "llkeyboard.h"
+#include "llmenugl.h"
+#include "llmultigesture.h"
+#include "llscrolllistctrl.h"
+#include "llcheckboxctrl.h"
+#include "lltrans.h"
+#include "llviewergesture.h"
+#include "llviewermenu.h"
+#include "llviewerinventory.h"
+#include "llviewercontrol.h"
+#include "llfloaterperms.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 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");
+}
+
+//=========================================================================
+#if 0
+BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
+{
+ return LLStringUtil::precedesDict( a->getName(), b->getName() );
+}
+
+class LLFloaterGestureObserver : public LLGestureManagerObserver
+{
+public:
+ LLFloaterGestureObserver(LLFloaterGesture* floater) : mFloater(floater) {}
+ virtual ~LLFloaterGestureObserver() {}
+ virtual void changed() { mFloater->refreshAll(); }
+
+private:
+ LLFloaterGesture* mFloater;
+};
+//-----------------------------
+// GestureCallback
+//-----------------------------
+
+class GestureShowCallback : public LLInventoryCallback
+{
+public:
+ void fire(const LLUUID &inv_item)
+ {
+ LLPreviewGesture::show(inv_item, LLUUID::null);
+
+ LLInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Gestures"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+ item->setPermissions(perm);
+ item->updateServer(FALSE);
+ }
+ }
+};
+
+class GestureCopiedCallback : public LLInventoryCallback
+{
+private:
+ LLFloaterGesture* mFloater;
+
+public:
+ GestureCopiedCallback(LLFloaterGesture* floater): mFloater(floater)
+ {}
+ void fire(const LLUUID &inv_item)
+ {
+ if(mFloater)
+ {
+ mFloater->addGesture(inv_item,NULL,mFloater->getChild<LLScrollListCtrl>("gesture_list"));
+
+ // EXP-1909 (Pasted gesture displayed twice)
+ // The problem is that addGesture is called here for the second time for the same item (which is copied)
+ // First time addGesture is called from LLFloaterGestureObserver::changed(), which is a callback for inventory
+ // change. So we need to refresh the gesture list to avoid duplicates.
+ mFloater->refreshAll();
+ }
+ }
+};
+
+#endif
+
+//=========================================================================
+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()
+{
+ // LLGestureMgr::instance().removeObserver(mObserver);
+ // delete mObserver;
+ // mObserver = NULL;
+ // gInventory.removeObserver(this);
+}
+
+
+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);
+
+ childSetCommitCallback(BUTTON_DELETE, [this](LLUICtrl *, void*) { onDeleteSelected(); }, nullptr);
+
+ 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::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();
+
+ if (context == PARAMETER_REGION)
+ {
+ LLEnvironment::instance().updateRegion(asset_id, -1, -1);
+ }
+ 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, -1, -1);
+ }
+ 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..10d64eaa93
--- /dev/null
+++ b/indra/newview/llfloatermyenvironment.h
@@ -0,0 +1,132 @@
+/**
+ * @file llfloatermyenvironment.h
+ * @brief Read-only list of gestures from your inventory.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/**
+ * (Also has legacy gesture editor for testing.)
+ */
+
+#ifndef LL_LLFLOATERMYENVIRONMENT_H
+#define LL_LLFLOATERMYENVIRONMENT_H
+#include <vector>
+
+#include "llfloater.h"
+#include "llinventoryobserver.h"
+#include "llinventoryfilter.h"
+
+class LLView;
+class LLButton;
+class LLLineEditor;
+class LLComboBox;
+class LLViewerGesture;
+class LLGestureOptions;
+class LLMenuGL;
+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;
+ U64 mTypeFilter;
+ LLInventoryFilter::EFolderShow mShowFolders;
+ LLUUID mSelectedAsset;
+
+ void onShowFoldersChange();
+ void onFilterCheckChange();
+ 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);
+
+#if 0
+ virtual void done ();
+ void refreshAll();
+ /**
+ * @brief Add new scrolllistitem into gesture_list.
+ * @param item_id inventory id of gesture
+ * @param gesture can be NULL , if item was not loaded yet
+ */
+ void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);
+
+protected:
+ // Reads from the gesture manager's list of active gestures
+ // and puts them in this list.
+ void buildGestureList();
+ void playGesture(LLUUID item_id);
+private:
+ void addToCurrentOutFit();
+ /**
+ * @brief This method is using to collect selected items.
+ * In some places gesture_list can be rebuilt by gestureObservers during iterating data from LLScrollListCtrl::getAllSelected().
+ * Therefore we have to copy these items to avoid viewer crash.
+ * @see LLFloaterGesture::onActivateBtnClick
+ */
+ void getSelectedIds(uuid_vec_t& ids);
+ bool isActionEnabled(const LLSD& command);
+ /**
+ * @brief Activation rules:
+ * According to Gesture Spec:
+ * 1. If all selected gestures are active: set to inactive
+ * 2. If all selected gestures are inactive: set to active
+ * 3. If selected gestures are in a mixed state: set all to active
+ */
+ void onActivateBtnClick();
+ void onClickEdit();
+ void onClickPlay();
+ void onClickNew();
+ void onCommitList();
+ void onCopyPasteAction(const LLSD& command);
+ void onDeleteSelected();
+
+ LLUUID mSelectedID;
+ LLUUID mGestureFolderID;
+ LLScrollListCtrl* mGestureList;
+
+ LLFloaterGestureObserver* mObserver;
+#endif
+};
+
+
+#endif
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index c9a689281e..7cde061515 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -161,7 +161,7 @@ void LLFloaterNameDesc::onBtnOK( )
{
getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
+ LLAssetStorage::LLStoreAssetCallback callback;
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).
if (can_afford_transaction(expected_upload_cost))
@@ -169,7 +169,7 @@ void LLFloaterNameDesc::onBtnOK( )
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,
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 2281ea1496..3968f43485 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()
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 7aff9fb586..43b359e003 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -811,6 +811,17 @@ void LLFloaterPreferenceGraphicsAdvanced::onVertexShaderEnable()
refreshEnabledGraphics();
}
+void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable()
+{
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->refresh();
+ }
+
+ refreshEnabledGraphics();
+}
+
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics()
{
refreshEnabledState();
@@ -1351,6 +1362,13 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
ctrl_ssao->setEnabled(enabled);
ctrl_dof->setEnabled(enabled);
+#if USE_ADVANCED_ATMOSPHERICS
+ LLCheckBoxCtrl* ctrl_advanced_atmo = getChild<LLCheckBoxCtrl>("UseAdvancedAtmo");
+
+ bool advanced_atmo_enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseAdvancedAtmospherics");
+ ctrl_advanced_atmo->setEnabled(advanced_atmo_enabled);
+#endif
+
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
ctrl_shadow->setEnabled(enabled);
@@ -2724,7 +2742,10 @@ void LLPanelPreferenceGraphics::setHardwareDefaults()
LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
: LLFloater(key)
{
- mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onVertexShaderEnable, this));
+ mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onVertexShaderEnable, this));
+#if USE_ADVANCED_ATMOSPHERICS
+ mCommitCallbackRegistrar.add("Pref.AdvancedAtmosphericsEnable", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable, this));
+#endif
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 8339a18296..973ca25c37 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -295,6 +295,7 @@ class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
void refresh();
// callback for when client turns on shaders
void onVertexShaderEnable();
+ void onAdvancedAtmosphericsEnable();
LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced);
};
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index a0522c99c2..c8ed43871d 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -52,8 +52,6 @@
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
-#include "lldaycyclemanager.h"
-#include "llenvmanager.h"
#include "llestateinfomodel.h"
#include "llfilepicker.h"
#include "llfloatergodtools.h" // for send_sim_wide_deletes()
@@ -87,7 +85,6 @@
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
#include "llvlcomposition.h"
-#include "llwaterparammanager.h"
#include "lltrans.h"
#include "llagentui.h"
#include "llmeshrepository.h"
@@ -98,6 +95,7 @@
#include "llexperiencecache.h"
#include "llpanelexperiences.h"
#include "llcorehttputil.h"
+#include "llenvironment.h"
const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
@@ -178,6 +176,40 @@ void unpack_request_params(
}
*/
+class LLPanelRegionEnvironment : public LLPanelEnvironmentInfo
+{
+public:
+ 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(); }
+
+ bool refreshFromRegion(LLViewerRegion* region);
+ void refreshFromEstate();
+
+ virtual BOOL postBuild() override;
+
+ virtual S32 getParcelId() override { return INVALID_PARCEL_ID; }
+
+protected:
+ static const U32 DIRTY_FLAG_OVERRIDE;
+
+ virtual void doApply() override;
+
+ virtual void refreshFromSource() override;
+
+ bool doUpdateEstate(const LLSD& notification, const LLSD& response);
+
+ void onChkAllowOverride(bool value);
+
+private:
+ bool mAllowOverride;
+
+};
+
bool estate_dispatch_initialized = false;
@@ -192,7 +224,8 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice;
LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
- : LLFloater(seed)
+ : LLFloater(seed),
+ mEnvironmentPanel(NULL)
{}
BOOL LLFloaterRegionInfo::postBuild()
@@ -223,10 +256,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);
@@ -245,7 +278,7 @@ BOOL LLFloaterRegionInfo::postBuild()
panel->buildFromFile("panel_region_experiences.xml");
mTab->addTabPanel(panel);
}
-
+
gMessageSystem->setHandlerFunc(
"EstateOwnerMessage",
&processEstateOwnerRequest);
@@ -337,13 +370,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();
@@ -543,6 +576,7 @@ void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region)
std::mem_fun(&LLPanelRegionInfo::refreshFromRegion),
#endif
region));
+ mEnvironmentPanel->refreshFromRegion(region);
}
// public
@@ -553,6 +587,7 @@ void LLFloaterRegionInfo::refresh()
{
(*iter)->refresh();
}
+ mEnvironmentPanel->refresh();
}
void LLFloaterRegionInfo::enableTopButtons()
@@ -2368,8 +2403,6 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
estate_info.setAllowAccessOverride(getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean());
- // JIGGLYPUFF
- //estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean());
// send the update to sim
estate_info.sendEstateInfo();
}
@@ -3086,604 +3119,6 @@ bool LLDispatchSetEstateExperience::operator()(
}
-
-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);
@@ -3942,3 +3377,140 @@ void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id )
onChangeAnything();
}
+
+//=========================================================================
+const U32 LLPanelRegionEnvironment::DIRTY_FLAG_OVERRIDE(0x01 << 4);
+
+LLPanelRegionEnvironment::LLPanelRegionEnvironment():
+ LLPanelEnvironmentInfo(),
+ mAllowOverride(false)
+{
+ LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+ estate_info.setCommitCallback(boost::bind(&LLPanelRegionEnvironment::refreshFromEstate, this));
+ estate_info.setUpdateCallback(boost::bind(&LLPanelRegionEnvironment::refreshFromEstate, this));
+}
+
+
+BOOL LLPanelRegionEnvironment::postBuild()
+{
+ if (!LLPanelEnvironmentInfo::postBuild())
+ return FALSE;
+
+ getChild<LLUICtrl>(RDO_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()); });
+ return TRUE;
+}
+
+
+void LLPanelRegionEnvironment::refresh()
+{
+ if (!mCurrentEnvironment)
+ {
+ refreshFromSource();
+ return;
+ }
+
+ refreshFromEstate();
+ LLPanelEnvironmentInfo::refresh();
+
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setValue(mAllowOverride);
+}
+
+bool LLPanelRegionEnvironment::refreshFromRegion(LLViewerRegion* region)
+{
+ if (!region)
+ {
+ setNoSelection(true);
+ setControlsEnabled(false);
+ }
+ setNoSelection(false);
+
+ if (gAgent.getRegion()->getRegionID() != region->getRegionID())
+ {
+ setCrossRegion(true);
+ }
+ setCrossRegion(false);
+
+ refreshFromSource();
+ return true;
+}
+
+void LLPanelRegionEnvironment::refreshFromEstate()
+{
+ const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+
+ mAllowOverride = estate_info.getAllowEnvironmentOverride();
+}
+
+void LLPanelRegionEnvironment::refreshFromSource()
+{
+ LLHandle<LLPanel> that_h = getHandle();
+
+ LLEnvironment::instance().requestRegion(
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+
+ setControlsEnabled(false);
+}
+
+void LLPanelRegionEnvironment::doApply()
+{
+ LLPanelEnvironmentInfo::doApply();
+
+ if (getIsDirtyFlag(DIRTY_FLAG_OVERRIDE))
+ {
+ LLNotification::Params params("ChangeLindenEstate");
+ //params.functor.function(boost::bind(&LLPanelEstateInfo::doUpdateEstate, this, _1, _2));
+ params.functor.function([this](const LLSD& notification, const LLSD& response) { doUpdateEstate(notification, response); });
+
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ // trying to change reserved estate, warn
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ // for normal estates, just make the change
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+
+ }
+}
+
+bool LLPanelRegionEnvironment::doUpdateEstate(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:
+ default:
+ break;
+ }
+ return false;
+}
+
+void LLPanelRegionEnvironment::onChkAllowOverride(bool value)
+{
+ if (!value)
+ {
+ LLNotificationsUtil::add("EstateParcelEnvironmentOverride");
+ }
+
+ setDirtyFlag(DIRTY_FLAG_OVERRIDE);
+ mAllowOverride = value;
+}
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index c9d0e51640..6d64ae1d60 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -34,8 +34,8 @@
#include "llhost.h"
#include "llpanel.h"
#include "llextendedstatus.h"
+#include "llpanelenvironment.h"
-#include "llenvmanager.h" // for LLEnvironmentSettings
#include "lleventcoro.h"
class LLAvatarName;
@@ -64,13 +64,9 @@ class LLPanelEstateCovenant;
class LLPanelExperienceListEditor;
class LLPanelExperiences;
class LLPanelRegionExperiences;
+class LLPanelRegionEnvironment;
class LLEventTimer;
-class LLEnvironmentSettings;
-class LLWLParamManager;
-class LLWaterParamManager;
-class LLWLParamSet;
-class LLWaterParamSet;
class LLFloaterRegionInfo : public LLFloater
{
@@ -121,6 +117,7 @@ protected:
LLTabContainer* mTab;
typedef std::vector<LLPanelRegionInfo*> info_panels_t;
info_panels_t mInfoPanels;
+ LLPanelRegionEnvironment *mEnvironmentPanel;
//static S32 sRequestSerial; // serial # of last EstateOwnerRequest
static LLUUID sRequestInvoice;
};
@@ -415,69 +412,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(){}
diff --git a/indra/newview/llflyoutcombobtn.cpp b/indra/newview/llflyoutcombobtn.cpp
new file mode 100644
index 0000000000..b008ee13be
--- /dev/null
+++ b/indra/newview/llflyoutcombobtn.cpp
@@ -0,0 +1,156 @@
+/**
+ * @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::onFlyoutButton(LLUICtrl *ctrl, const LLSD &data)
+{
+ S32 x, y;
+ LLUI::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..b0dd4abadf
--- /dev/null
+++ b/indra/newview/llflyoutcombobtn.h
@@ -0,0 +1,75 @@
+/**
+ * @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);
+
+ 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..06a908cccc 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -49,8 +49,9 @@ public:
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/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 6b1e196182..486e077b9b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -588,8 +588,6 @@ void LLHUDText::renderAllHUD()
LLVertexBuffer::unbind();
- LLVertexBuffer::unbind();
-
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index e4b6c3b554..3b6778892f 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>
@@ -1414,6 +1418,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() << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL;
@@ -3930,6 +3942,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"));
@@ -4023,10 +4036,18 @@ 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);
+
}
else
{
@@ -4289,6 +4310,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:
@@ -5078,6 +5100,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
@@ -5794,6 +5821,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();
@@ -6867,6 +6895,154 @@ void LLMeshBridge::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();
+ LL_WARNS("LAPRAS") << "Locally applying asset ID " << asset_id << LL_ENDL;
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ }
+ else if ("apply_settings_parcel" == action)
+ {
+ // Single item only
+ LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
+ if (!item)
+ return;
+ LLUUID asset_id = item->getAssetUUID();
+
+ LLParcel *parcel = LLViewerParcelMgr::instance().getAgentOrSelectedParcel();
+ if (!parcel)
+ {
+ LL_WARNS("INVENTORY") << "could not identify parcel." << LL_ENDL;
+ return;
+ }
+ S32 parcel_id = parcel->getLocalID();
+
+ LL_WARNS("LAPRAS") << "Applying asset ID " << asset_id << " to parcel " << parcel_id << LL_ENDL;
+ LLEnvironment::instance().updateParcel(parcel_id, asset_id, -1, -1);
+ }
+ else if ("apply_settings_region" == action)
+ {
+ // Single item only
+ LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
+ if (!item)
+ return;
+ LLUUID asset_id = item->getAssetUUID();
+
+ LL_WARNS("LAPRAS") << "Applyng asset id " << asset_id << " to region." << LL_ENDL;
+
+ LLEnvironment::instance().updateRegion(asset_id, -1, -1);
+ }
+ else
+ LLItemBridge::performAction(model, action);
+}
+
+void LLSettingsBridge::openItem()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ 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 |
@@ -7226,6 +7402,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)
@@ -7264,6 +7474,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;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index ce06e8fffc..73f20d2146 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;
@@ -620,6 +623,30 @@ protected:
};
+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
//
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 9193613e9f..a9640a2264 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),
@@ -325,12 +326,26 @@ 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;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_EMPTYFOLDERS
// Pass if this item is a folder and is not a system folder that should be hidden
@@ -626,6 +641,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;
@@ -1241,6 +1262,11 @@ U64 LLInventoryFilter::getFilterWearableTypes() const
return mFilterOps.mFilterWearableTypes;
}
+U64 LLInventoryFilter::getFilterSettingsTypes() const
+{
+ return mFilterOps.mFilterSettingsTypes;
+}
+
bool LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 01754ed023..9fb986f21d 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -47,18 +47,19 @@ public:
enum EFilterType {
FILTERTYPE_NONE = 0,
- FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
- FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
- FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
- FILTERTYPE_DATE = 0x1 << 3, // search by date range
- FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
+ FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
+ FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
+ FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
+ FILTERTYPE_DATE = 0x1 << 3, // search by date range
+ FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5, // pass if folder is not a system folder to be hidden if empty
FILTERTYPE_MARKETPLACE_ACTIVE = 0x1 << 6, // pass if folder is a marketplace active folder
FILTERTYPE_MARKETPLACE_INACTIVE = 0x1 << 7, // pass if folder is a marketplace inactive folder
FILTERTYPE_MARKETPLACE_UNASSOCIATED = 0x1 << 8, // pass if folder is a marketplace non associated (no market ID) folder
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_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
@@ -118,6 +119,7 @@ public:
Optional<U32> types;
Optional<U64> object_types,
wearable_types,
+ settings_types,
category_types;
Optional<EFilterLink> links;
Optional<LLUUID> uuid;
@@ -131,7 +133,8 @@ public:
: types("filter_types", FILTERTYPE_OBJECT),
object_types("object_types", 0xffffFFFFffffFFFFULL),
wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
- category_types("category_types", 0xffffFFFFffffFFFFULL),
+ settings_types("settings_types", 0xffffFFFFffffFFFFULL),
+ category_types("category_types", 0xffffFFFFffffFFFFULL),
links("links", FILTERLINK_INCLUDE_LINKS),
uuid("uuid"),
date_range("date_range"),
@@ -145,10 +148,11 @@ public:
FilterOps(const Params& = Params());
U32 mFilterTypes;
- U64 mFilterObjectTypes, // For _OBJECT
- mFilterWearableTypes,
- mFilterLinks,
- mFilterCategoryTypes; // For _CATEGORY
+ U64 mFilterObjectTypes, // For _OBJECT
+ mFilterWearableTypes,
+ mFilterSettingsTypes, // for _SETTINGS
+ mFilterLinks,
+ mFilterCategoryTypes; // For _CATEGORY
LLUUID mFilterUUID; // for UUID
time_t mMinDate,
@@ -186,11 +190,14 @@ public:
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
U64 getFilterWearableTypes() const;
+ U64 getFilterSettingsTypes() 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();
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 030c967019..b0004c5e58 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -2395,10 +2395,29 @@ 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);
+ 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 = (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/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index d0df1c94d5..323d19b68a 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
{
@@ -92,6 +93,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"));
@@ -167,8 +173,14 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
break;
case LLAssetType::AT_MESH:
idx = LLInventoryType::ICONNAME_MESH;
+ break;
+ case LLAssetType::AT_SETTINGS:
+ // TODO: distinguish between Sky and Water settings.
+ idx = assignSettingsIcon(misc_flag);
+ break;
case LLAssetType::AT_UNKNOWN:
idx = LLInventoryType::ICONNAME_UNKNOWN;
+ break;
default:
break;
}
@@ -188,3 +200,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 2b9607f7a2..1c6d9fba9d 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1818,7 +1818,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
return;
}
- if (LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
+ if (LLAssetType::lookup(item->getType()) == LLAssetType::BADLOOKUP)
{
LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName()
<< " type: " << item->getType()
@@ -2593,6 +2593,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
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 1481992f43..002c7a3215 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -144,6 +144,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mShowEmptyMessage(p.show_empty_message),
+ mSuppressFolderMenu(p.suppress_folder_menu),
mViewsInitialized(false),
mInvFVBridgeBuilder(NULL),
mInventoryViewModel(p.name),
@@ -191,6 +192,7 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
p.use_label_suffix = mParams.use_label_suffix;
p.allow_multiselect = mAllowMultiSelect;
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;
@@ -377,6 +379,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 +394,6 @@ const std::string LLInventoryPanel::getFilterSubString()
return getFilter().getFilterSubString();
}
-
void LLInventoryPanel::setSortOrder(U32 order)
{
LLInventorySort sorter(order);
@@ -1122,6 +1128,11 @@ void LLInventoryPanel::clearSelection()
mSelectThisID.setNull();
}
+LLInventoryPanel::selected_items_t LLInventoryPanel::getSelectedItems() const
+{
+ return mFolderRoot.get()->getSelectionList();
+}
+
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
{
// Schedule updating the folder view context menu when all selected items become complete (STORM-373).
@@ -1749,6 +1760,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..90fd659522 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -97,6 +97,7 @@ public:
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;
@@ -111,6 +112,7 @@ public:
inventory("", &gInventory),
allow_multi_select("allow_multi_select", 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),
@@ -144,6 +146,8 @@ public:
virtual ~LLInventoryPanel();
public:
+ typedef std::set<LLFolderViewItem*> selected_items_t;
+
LLInventoryModel* getModel() { return mInventory; }
LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
@@ -168,6 +172,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 +182,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);
@@ -256,6 +263,7 @@ protected:
bool mAllowMultiSelect;
bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons
bool mShowEmptyMessage;
+ bool mSuppressFolderMenu;
LLHandle<LLFolderView> mFolderRoot;
LLScrollContainer* mScroller;
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 59e14e6cc0..7fcd6f4361 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -48,7 +48,7 @@ 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
@@ -646,3 +646,238 @@ void LLJoystickCameraTrack::onHeldDown()
gAgentCamera.setPanDownKey(getOrbitRate());
}
}
+
+//-------------------------------------------------------------------------------
+// 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..ee66088b56 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
{
@@ -178,4 +179,47 @@ public:
virtual void onHeldDown();
};
+//
+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/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index 9c00243f44..c243f8b4f0 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -272,7 +272,7 @@ void LLLandmarkActions::createLandmarkHere(
name, desc,
LLAssetType::AT_LANDMARK,
LLInventoryType::IT_LANDMARK,
- NOT_WEARABLE, PERM_ALL,
+ NO_INV_SUBTYPE, PERM_ALL,
NULL);
}
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
new file mode 100644
index 0000000000..04623c4452
--- /dev/null
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -0,0 +1,664 @@
+/**
+ * @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;
+ mUpdateTimer.reset();
+ 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)
+{
+ F32 saturation = 0.3f;
+ if (dir.mV[VZ] < -0.02f)
+ {
+ 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;
+ }
+
+ // undo OGL_TO_CFR_ROTATION and negate vertical direction.
+ LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
+
+ calcSkyColorWLVert(Pn, vars);
+
+ LLColor3 sky_color = calcSkyColorWLFrag(Pn, vars);
+ if (isShiny)
+ {
+ 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);
+}
+
+void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars)
+{
+// LEGACY_ATMOSPHERICS
+ //LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ 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;
+
+ vars.horizontalProjection[0] = LLVector2(Pn[0], Pn[2]);
+ vars.horizontalProjection[0] /= - 2.f * 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;
+
+ // Calculate relative weights
+ LLColor3 temp2(0.f, 0.f, 0.f);
+ LLColor3 temp1 = vars.light_transmittance;
+
+ 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 + sun_norm[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(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)
+ 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
+ vars.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
+ vars.hazeColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient));
+
+ // Final atmosphere additive
+ componentMultBy(vars.hazeColor, LLColor3::white - temp1);
+
+ sunlight = vars.sunlight;
+ temp2.mV[1] = llmax(0.f, sun_norm[1] * 2.f);
+ temp2.mV[1] = 1.f / temp2.mV[1];
+ componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
+
+ // 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));
+
+ 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 = vars.hazeColor.brightness();
+
+ if (Pn[1] < -0.05f)
+ {
+ vars.hazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness;
+ }
+
+ if (Pn[1] > -0.1f)
+ {
+ vars.hazeColor = colorMix(LLColor3::white * haze_brightness, vars.hazeColor, fabs((Pn[1] + 0.05f) * -20.f));
+ }
+ }
+}
+
+LLColor3 LLAtmospherics::calcSkyColorWLFrag(LLVector3 & Pn, AtmosphericsVars& vars)
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+
+ LLColor3 res;
+ LLColor3 color0 = vars.hazeColor;
+
+ if (!gPipeline.canUseWindLightShaders())
+ {
+ res = psky->gammaCorrect(color0 * 2.0f);
+ }
+ else
+ {
+ res = color0;
+ }
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ F32 gamma = psky->getGamma();
+ 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)
+ {
+ 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 = vars.hazeColor;
+ break;
+ }
+#endif // LL_RELEASE_FOR_DOWNLOAD
+ return res;
+}
+
+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.max_y = psky->getMaxY();
+ vars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+ 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();
+
+ 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->getWaterFogDensity();
+ 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;
+}
diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h
new file mode 100644
index 0000000000..1979e93cdd
--- /dev/null
+++ b/indra/newview/lllegacyatmospherics.h
@@ -0,0 +1,280 @@
+/**
+ * @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)
+ , 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()
+ {
+ horizontalProjection[0] = LLVector2(0,0);
+ horizontalProjection[1] = LLVector2(0,0);
+ }
+
+ LLColor3 hazeColor;
+ LLColor3 hazeColorBelowCloud;
+ LLColor3 cloudColorSun;
+ LLColor3 cloudColorAmbient;
+ F32 cloudDensity;
+ LLVector2 horizontalProjection[2];
+ LLColor3 blue_density;
+ LLColor3 blue_horizon;
+ F32 haze_density;
+ F32 haze_horizon;
+ F32 density_multiplier;
+ F32 max_y;
+ LLVector4 sun_norm;
+ LLColor3 sunlight;
+ LLColor3 ambient;
+ LLColor3 glow;
+ F32 cloud_shadow;
+ F32 dome_radius;
+ F32 dome_offset;
+ LLColor3 light_atten;
+ LLColor3 light_transmittance;
+};
+
+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);
+
+protected:
+
+ void calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars);
+ LLColor3 calcSkyColorWLFrag(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;
+ LLFrameTimer mUpdateTimer;
+};
+
+#endif
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 11bc1425f9..c01a2fbf8a 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -44,7 +44,6 @@
// newview includes
#include "llagent.h"
-#include "llenvmanager.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
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 2c1980922a..d0ef9dd326 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2663,7 +2663,7 @@ void LLMeshUploadThread::requestWholeModelFee()
{
ms_sleep(sleep_time);
sleep_time = llmin(250U, sleep_time + sleep_time);
- mHttpRequest->update(0);
+ mHttpRequest->update(0);
}
if (isDiscarded())
{
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index b2b6de94b3..278d83bab7 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1215,7 +1215,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 +1222,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;
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
new file mode 100644
index 0000000000..0d36fce90a
--- /dev/null
+++ b/indra/newview/llpaneleditsky.cpp
@@ -0,0 +1,747 @@
+/**
+* @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_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_IMAGE("sun_image");
+ const std::string FIELD_SKY_SUN_SCALE("sun_scale");
+ const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
+ const std::string FIELD_SKY_MOON_IMAGE("moon_image");
+ const std::string FIELD_SKY_MOON_SCALE("moon_scale");
+
+ 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 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);
+}
+
+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(); });
+
+ refresh();
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelSettingsSkyAtmosTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsSky::setEnabled(enabled);
+ 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);
+}
+
+void LLPanelSettingsSkyAtmosTab::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ 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());
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->setValue(mSkySettings->getDensityMultiplier());
+ getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->setValue(mSkySettings->getDistanceMultiplier());
+ getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->setValue(mSkySettings->getMaxY());
+
+}
+
+//-------------------------------------------------------------------------
+void LLPanelSettingsSkyAtmosTab::onAmbientLightChanged()
+{
+ mSkySettings->setAmbientColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->get() * SLIDER_SCALE_SUN_AMBIENT));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onBlueHorizonChanged()
+{
+ mSkySettings->setBlueHorizon(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onBlueDensityChanged()
+{
+ mSkySettings->setBlueDensity(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onHazeHorizonChanged()
+{
+ mSkySettings->setHazeHorizon(getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onHazeDensityChanged()
+{
+ mSkySettings->setHazeDensity(getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onSceneGammaChanged()
+{
+ mSkySettings->setGamma(getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onDensityMultipChanged()
+{
+ mSkySettings->setDensityMultiplier(getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onDistanceMultipChanged()
+{
+ mSkySettings->setDistanceMultiplier(getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onMaxAltChanged()
+{
+ mSkySettings->setMaxY(getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->getValue().asReal());
+ 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_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<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setAllowLocalTexture(FALSE);
+
+ 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);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->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(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ 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());
+
+ 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->getCloudPosDensity1().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()
+{
+ mSkySettings->setCloudColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->get()));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudCoverageChanged()
+{
+ mSkySettings->setCloudShadow(getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudScaleChanged()
+{
+ mSkySettings->setCloudScale(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudScrollChanged()
+{
+ LLVector2 scroll(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_XY)->getValue());
+ mSkySettings->setCloudScrollRate(scroll);
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudMapChanged()
+{
+ mSkySettings->setCloudNoiseTextureId(getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->getValue().asUUID());
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudDensityChanged()
+{
+ 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()
+{
+ 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_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<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setAllowLocalTexture(FALSE);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
+ 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::GetBlankSunTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setAllowNoTexture(TRUE);
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setAllowLocalTexture(FALSE);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonScaleChanged(); });
+
+ refresh();
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelSettingsSkySunMoonTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsSky::setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setEnabled(enabled);
+}
+
+void LLPanelSettingsSkySunMoonTab::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_MOON_COLOR)->set(mSkySettings->getSunlightColor() / SLIDER_SCALE_SUN_AMBIENT);
+
+ LLColor3 glow(mSkySettings->getGlow());
+
+ 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<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mSkySettings->getSunRotation());
+ getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId());
+ getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mSkySettings->getSunScale());
+ getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mSkySettings->getMoonRotation());
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId());
+ getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setValue(mSkySettings->getMoonScale());
+}
+
+//-------------------------------------------------------------------------
+void LLPanelSettingsSkySunMoonTab::onSunMoonColorChanged()
+{
+ LLColor3 color(getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_MOON_COLOR)->get());
+
+ color *= SLIDER_SCALE_SUN_AMBIENT;
+
+ mSkySettings->setSunlightColor(color);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onGlowChanged()
+{
+ LLColor3 glow(getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->getValue().asReal(), 0.0f, getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->getValue().asReal());
+
+ 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()
+{
+ mSkySettings->setStarBrightness(getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunRotationChanged()
+{
+ mSkySettings->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunScaleChanged()
+{
+ mSkySettings->setSunScale((getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->getValue().asReal()));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunImageChanged()
+{
+ mSkySettings->setSunTextureId(getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->getValue().asUUID());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged()
+{
+ mSkySettings->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonImageChanged()
+{
+ mSkySettings->setMoonTextureId(getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->getValue().asUUID());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonScaleChanged()
+{
+ mSkySettings->setMoonScale((getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->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);
+
+ 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(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ // 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..b34271f610
--- /dev/null
+++ b/indra/newview/llpaneleditsky.h
@@ -0,0 +1,165 @@
+/**
+* @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 "llfloaterfixedenvironment.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();
+};
+
+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 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 onSunScaleChanged();
+ void onSunImageChanged();
+ void onMoonRotationChanged();
+ void onMoonScaleChanged();
+ 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..40d84d74bd
--- /dev/null
+++ b/indra/newview/llpaneleditwater.cpp
@@ -0,0 +1,243 @@
+/**
+* @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(TRUE);
+ setAllChildrenEnabled(TRUE);
+ 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->getFresnelOffset());
+ 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()
+{
+ mWaterSettings->setWaterFogColor(LLColor3(mClrFogColor->get()));
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFogDensityChanged()
+{
+ mWaterSettings->setWaterFogDensity(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFogUnderWaterChanged()
+{
+ mWaterSettings->setFogMod(getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onNormalMapChanged()
+{
+ mWaterSettings->setNormalMapID(mTxtNormalMap->getImageAssetID());
+ setIsDirty();
+}
+
+
+void LLPanelSettingsWaterMainTab::onLargeWaveChanged()
+{
+ LLVector2 vect(getChild<LLUICtrl>(FIELD_WATER_WAVE1_XY)->getValue());
+ vect *= -1.0; // Flip so that north and east are -
+ LL_WARNS("LAPRAS") << "Changing Large Wave from " << mWaterSettings->getWave1Dir() << " -> " << vect << LL_ENDL;
+ mWaterSettings->setWave1Dir(vect);
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onSmallWaveChanged()
+{
+ LLVector2 vect(getChild<LLUICtrl>(FIELD_WATER_WAVE2_XY)->getValue());
+ vect *= -1.0; // Flip so that north and east are -
+ LL_WARNS("LAPRAS") << "Changing Small Wave from " << mWaterSettings->getWave2Dir() << " -> " << vect << LL_ENDL;
+ mWaterSettings->setWave2Dir(vect);
+ setIsDirty();
+}
+
+
+void LLPanelSettingsWaterMainTab::onNormalScaleChanged()
+{
+ 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());
+ LL_WARNS("LAPRAS") << "Changing normal scale from " << mWaterSettings->getNormalScale() << " -> " << vect << LL_ENDL;
+ mWaterSettings->setNormalScale(vect);
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFresnelScaleChanged()
+{
+ mWaterSettings->setFresnelScale(getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFresnelOffsetChanged()
+{
+ mWaterSettings->setFresnelOffset(getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onScaleAboveChanged()
+{
+ mWaterSettings->setScaleAbove(getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onScaleBelowChanged()
+{
+ mWaterSettings->setScaleBelow(getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onBlurMultipChanged()
+{
+ 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..ab2dc47bcc
--- /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 "llfloaterfixedenvironment.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/llpanelenvironment.cpp b/indra/newview/llpanelenvironment.cpp
new file mode 100644
index 0000000000..20aaf258f8
--- /dev/null
+++ b/indra/newview/llpanelenvironment.cpp
@@ -0,0 +1,777 @@
+/**
+ * @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 "llsettingsvo.h"
+
+#include "llappviewer.h"
+#include "llcallbacklist.h"
+#include "llviewerparcelmgr.h"
+
+//=========================================================================
+namespace
+{
+ const std::string FLOATER_DAY_CYCLE_EDIT("env_edit_extdaycycle");
+}
+
+//=========================================================================
+const std::string LLPanelEnvironmentInfo::RDG_ENVIRONMENT_SELECT("rdg_environment_select");
+const std::string LLPanelEnvironmentInfo::RDO_USEDEFAULT("rdo_use_xxx_setting");
+const std::string LLPanelEnvironmentInfo::RDO_USEINV("rdo_use_inv_setting");
+const std::string LLPanelEnvironmentInfo::RDO_USECUSTOM("rdo_use_custom_setting");
+const std::string LLPanelEnvironmentInfo::EDT_INVNAME("edt_inventory_name");
+const std::string LLPanelEnvironmentInfo::BTN_SELECTINV("btn_select_inventory");
+const std::string LLPanelEnvironmentInfo::BTN_EDIT("btn_edit");
+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::CHK_ALLOWOVERRIDE("chk_allow_override");
+const std::string LLPanelEnvironmentInfo::BTN_APPLY("btn_apply");
+const std::string LLPanelEnvironmentInfo::BTN_CANCEL("btn_cancel");
+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::STR_LABEL_USEDEFAULT("str_label_use_default");
+const std::string LLPanelEnvironmentInfo::STR_LABEL_USEREGION("str_label_use_region");
+const std::string LLPanelEnvironmentInfo::STR_LABEL_UNKNOWNINV("str_unknow_inventory");
+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 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 std::string alt_sliders[] = {
+ "sld1",
+ "sld2",
+ "sld3",
+};
+
+const std::string alt_labels[] = {
+ "alt1",
+ "alt2",
+ "alt3",
+ "ground",
+};
+
+//=========================================================================
+LLPanelEnvironmentInfo::LLPanelEnvironmentInfo():
+ mCurrentEnvironment(),
+ mDirtyFlag(0),
+ mCrossRegion(false),
+ mNoSelection(false),
+ mNoEnvironment(false),
+ mSettingsFloater(),
+ mEditFloater()
+{
+}
+
+LLPanelEnvironmentInfo::~LLPanelEnvironmentInfo()
+{
+ if (mChangeMonitor.connected())
+ mChangeMonitor.disconnect();
+}
+
+BOOL LLPanelEnvironmentInfo::postBuild()
+{
+ getChild<LLUICtrl>(RDG_ENVIRONMENT_SELECT)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onSwitchDefaultSelection(); });
+ getChild<LLUICtrl>(BTN_SELECTINV)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnSelect(); });
+ getChild<LLUICtrl>(BTN_EDIT)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnEdit(); });
+ getChild<LLUICtrl>(BTN_APPLY)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnApply(); });
+ getChild<LLUICtrl>(BTN_CANCEL)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnReset(); });
+
+ getChild<LLUICtrl>(SLD_DAYLENGTH)->setCommitCallback([this](LLUICtrl *, const LLSD &value) { onSldDayLengthChanged(value.asReal()); });
+ getChild<LLUICtrl>(SLD_DAYOFFSET)->setCommitCallback([this](LLUICtrl *, const LLSD &value) { onSldDayOffsetChanged(value.asReal()); });
+
+ getChild<LLMultiSliderCtrl>(SLD_ALTITUDES)->setCommitCallback([this](LLUICtrl *cntrl, const LLSD &value) { onAltSliderCallback(cntrl, value); });
+
+ mChangeMonitor = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env) { onEnvironmentChanged(env); });
+
+ 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
+ {
+ LLFloaterSettingsPicker *picker = getSettingsPicker(false);
+ if (picker)
+ {
+ picker->closeFloater();
+ }
+
+ gIdleCallbacks.deleteFunction(onIdlePlay, this);
+ LLFloaterEditExtDayCycle *dayeditor = getEditFloater();
+ if (mCommitConnection.connected())
+ mCommitConnection.disconnect();
+
+ if (dayeditor)
+ {
+ if (dayeditor->isDirty())
+ dayeditor->refresh();
+ else
+ dayeditor->closeFloater();
+ }
+ }
+
+}
+
+void LLPanelEnvironmentInfo::refresh()
+{
+ if (gDisconnected)
+ return;
+
+ if (!setControlsEnabled(canEdit()))
+ return;
+
+ if (!mCurrentEnvironment)
+ {
+ return;
+ }
+
+ if ((!mCurrentEnvironment->mDayCycle) ||
+ ((mCurrentEnvironment->mParcelId == INVALID_PARCEL_ID) && (mCurrentEnvironment->mDayCycle->getAssetId() == LLSettingsDay::GetDefaultAssetId() )))
+ {
+ getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->setSelectedIndex(0);
+ getChild<LLUICtrl>(EDT_INVNAME)->setValue("");
+ }
+ else if (!mCurrentEnvironment->mDayCycle->getAssetId().isNull())
+ {
+ getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->setSelectedIndex(1);
+
+ LLUUID asset_id = mCurrentEnvironment->mDayCycle->getAssetId();
+
+ std::string inventoryname = getInventoryNameForAssetId(asset_id);
+
+ if (inventoryname.empty())
+ inventoryname = "(" + mCurrentEnvironment->mDayCycle->getName() + ")";
+
+ getChild<LLUICtrl>(EDT_INVNAME)->setValue(inventoryname);
+ }
+ else
+ { // asset id is null so this is a custom environment
+ getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->setSelectedIndex(2);
+ getChild<LLUICtrl>(EDT_INVNAME)->setValue("");
+ }
+
+ F32Hours daylength(mCurrentEnvironment->mDayLength);
+ F32Hours dayoffset(mCurrentEnvironment->mDayOffset);
+
+ if (dayoffset.value() > 8.0f)
+ dayoffset -= F32Hours(24.0);
+
+ getChild<LLSliderCtrl>(SLD_DAYLENGTH)->setValue(daylength.value());
+ getChild<LLSliderCtrl>(SLD_DAYOFFSET)->setValue(dayoffset.value());
+
+ udpateApparentTimeOfDay();
+
+ updateEditFloater(mCurrentEnvironment, canEdit());
+
+#if 1
+ // hiding the controls until Rider can get the simulator code to adjust altitudes done.
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(FALSE);
+#else
+ LLEnvironment::altitude_list_t altitudes = LLEnvironment::instance().getRegionAltitudes();
+ if (altitudes.size() > 0)
+ {
+ for (S32 idx = 0; idx < ALTITUDE_SLIDER_COUNT; ++idx)
+ {
+ LLMultiSliderCtrl *sld = getChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
+ sld->setSliderValue(alt_sliders[idx], altitudes[idx+1], FALSE);
+ updateAltLabel(alt_labels[idx], idx + 2, altitudes[idx+1]);
+ mAltitudes[alt_sliders[idx]] = AltitudeData(idx+1, idx, altitudes[idx+1]);
+ }
+ readjustAltLabels();
+ }
+#endif
+
+}
+
+std::string LLPanelEnvironmentInfo::getInventoryNameForAssetId(LLUUID asset_id)
+{
+ LLFloaterSettingsPicker *picker = getSettingsPicker();
+
+ if (!picker)
+ {
+ LL_WARNS("ENVPANEL") << "Couldn't instantiate picker." << LL_ENDL;
+ return std::string();
+ }
+
+ std::string name(picker->findItemName(asset_id, false, false));
+
+ if (name.empty())
+ return getString(STR_LABEL_UNKNOWNINV);
+ return name;
+}
+
+LLFloaterSettingsPicker * LLPanelEnvironmentInfo::getSettingsPicker(bool create)
+{
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mSettingsFloater.get());
+
+ // Show the dialog
+ if (!picker && create)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null, "SELECT SETTINGS");
+
+ mSettingsFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitted(data.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)
+ return;
+
+ if (!nextenv || !nextenv->mDayCycle || !enable)
+ {
+ if (mCommitConnection.connected())
+ mCommitConnection.disconnect();
+
+ if (dayeditor->isDirty())
+ dayeditor->refresh();
+ else
+ dayeditor->closeFloater();
+ }
+ else
+ {
+ // Ignore dirty
+ // If parcel selection changed whatever we do except saving to inventory with
+ // old settings will be invalid.
+ dayeditor->setEditDayCycle(nextenv->mDayCycle);
+ }
+}
+
+bool LLPanelEnvironmentInfo::setControlsEnabled(bool enabled)
+{
+ bool is_unavailable(false);
+ bool is_legacy = (mCurrentEnvironment) ? mCurrentEnvironment->mIsLegacy : true;
+
+ 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));
+ }
+
+ 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);
+
+ updateEditFloater(mCurrentEnvironment, false);
+
+ return false;
+ }
+ getChild<LLUICtrl>(PNL_SETTINGS)->setVisible(true);
+ getChild<LLUICtrl>(PNL_BUTTONS)->setVisible(true);
+ getChild<LLUICtrl>(PNL_DISABLED)->setVisible(false);
+
+#if 1
+ // hiding the controls until Rider can get the simulator code to adjust altitudes done.
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(FALSE);
+#else
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(isRegion());
+#endif
+
+ S32 rdo_selection = getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->getSelectedIndex();
+
+ getChild<LLUICtrl>(RDG_ENVIRONMENT_SELECT)->setEnabled(enabled);
+ getChild<LLUICtrl>(RDO_USEDEFAULT)->setEnabled(enabled && !is_legacy);
+ getChild<LLUICtrl>(RDO_USEINV)->setEnabled(false); // these two are selected automatically based on
+ getChild<LLUICtrl>(RDO_USECUSTOM)->setEnabled(false);
+ getChild<LLUICtrl>(EDT_INVNAME)->setEnabled(FALSE);
+ getChild<LLUICtrl>(BTN_SELECTINV)->setEnabled(enabled && !is_legacy);
+ getChild<LLUICtrl>(BTN_EDIT)->setEnabled(enabled);
+ getChild<LLUICtrl>(SLD_DAYLENGTH)->setEnabled(enabled && (rdo_selection != 0) && !is_legacy);
+ getChild<LLUICtrl>(SLD_DAYOFFSET)->setEnabled(enabled && (rdo_selection != 0) && !is_legacy);
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setEnabled(enabled && isRegion() && !is_legacy);
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setEnabled(enabled && isRegion() && !is_legacy);
+ getChild<LLUICtrl>(BTN_APPLY)->setEnabled(enabled && (mDirtyFlag != 0));
+ getChild<LLUICtrl>(BTN_CANCEL)->setEnabled(enabled && (mDirtyFlag != 0));
+
+ return true;
+}
+
+void LLPanelEnvironmentInfo::setApplyProgress(bool started)
+{
+// LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator");
+//
+// indicator->setVisible(started);
+//
+// if (started)
+// {
+// indicator->start();
+// }
+// else
+// {
+// indicator->stop();
+// }
+}
+
+void LLPanelEnvironmentInfo::setDirtyFlag(U32 flag)
+{
+ bool can_edit = canEdit();
+ mDirtyFlag |= flag;
+ getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && can_edit);
+ getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && can_edit);
+}
+
+void LLPanelEnvironmentInfo::clearDirtyFlag(U32 flag)
+{
+ bool can_edit = canEdit();
+ mDirtyFlag &= ~flag;
+ getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && can_edit);
+ getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && can_edit);
+}
+
+void LLPanelEnvironmentInfo::updateAltLabel(const std::string &alt_name, U32 sky_index, F32 alt_value)
+{
+ LLMultiSliderCtrl *sld = getChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
+ 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 text box
+ LLTextBox* text = getChild<LLTextBox>(alt_name);
+ if (text)
+ {
+ // move related text box
+ LLRect rect = text->getRect();
+ S32 height = rect.getHeight();
+ rect.mBottom = sld_bottom + (sld_offset / 2 + 1) + pos - (height / 2);
+ rect.mTop = rect.mBottom + height;
+ text->setRect(rect);
+
+ // 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());
+ }
+}
+
+void LLPanelEnvironmentInfo::readjustAltLabels()
+{
+ // Restore ground label position
+ LLView* icon = getChild<LLView>(ICN_GROUND);
+ LLTextBox* text = getChild<LLTextBox>(alt_labels[ALTITUDE_SLIDER_COUNT]); // one more field then sliders
+ LLRect ground_text_rect = text->getRect();
+ LLRect icon_rect = icon->getRect();
+ S32 height = ground_text_rect.getHeight();
+ ground_text_rect.mBottom = icon_rect.mBottom + (icon_rect.getHeight()/2) - (height/2);
+ ground_text_rect.mTop = ground_text_rect.mBottom + height;
+ text->setRect(ground_text_rect);
+
+ // Re-adjust all labels
+ // Very simple "adjust after the fact" method
+ // Note: labels are unordered, labels are 1 above sliders due to 'ground'
+
+ for (U32 i = 0; i < ALTITUDE_SLIDER_COUNT; i++)
+ {
+ LLTextBox* text_cmp = getChild<LLTextBox>(alt_labels[i]);
+
+ for (U32 j = i + 1; j <= ALTITUDE_SLIDER_COUNT; j++)
+ {
+ LLTextBox* text_intr = getChild<LLTextBox>(alt_labels[j]);
+ if (text_cmp && text_intr)
+ {
+ LLRect cmp_rect = text_cmp->getRect();
+ LLRect intr_rect = text_intr->getRect();
+ S32 shift = 0;
+ if (cmp_rect.mBottom <= intr_rect.mTop && cmp_rect.mBottom >= intr_rect.mBottom)
+ {
+ // Aproximate shift
+ // We probably will need more cycle runs over all labels to get accurate one
+ // At the moment single cycle should do since we have too little elements to do something complicated
+ shift = (cmp_rect.mBottom - intr_rect.mTop) / 2;
+ }
+ else if (cmp_rect.mTop >= intr_rect.mBottom && cmp_rect.mTop <= intr_rect.mTop)
+ {
+ // Aproximate shift
+ shift = (cmp_rect.mTop - intr_rect.mBottom) / 2;
+ }
+ if (shift != 0)
+ {
+ cmp_rect.translate(0, -shift);
+ text_cmp->setRect(cmp_rect);
+
+ intr_rect.translate(0, shift);
+ text_intr->setRect(intr_rect);
+ }
+ }
+ }
+ }
+}
+
+void LLPanelEnvironmentInfo::onSwitchDefaultSelection()
+{
+ bool can_edit = canEdit();
+ setDirtyFlag(DIRTY_FLAG_DAYCYCLE);
+
+ S32 rdo_selection = getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->getSelectedIndex();
+ getChild<LLUICtrl>(SLD_DAYLENGTH)->setEnabled(can_edit && (rdo_selection != 0));
+ getChild<LLUICtrl>(SLD_DAYOFFSET)->setEnabled(can_edit && (rdo_selection != 0));
+}
+
+void LLPanelEnvironmentInfo::onSldDayLengthChanged(F32 value)
+{
+ F32Hours daylength(value);
+
+ mCurrentEnvironment->mDayLength = daylength;
+ setDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+
+ udpateApparentTimeOfDay();
+}
+
+void LLPanelEnvironmentInfo::onSldDayOffsetChanged(F32 value)
+{
+ F32Hours dayoffset(value);
+
+ if (dayoffset.value() < 0.0f)
+ dayoffset += F32Hours(24.0);
+
+ mCurrentEnvironment->mDayOffset = dayoffset;
+ setDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+
+ udpateApparentTimeOfDay();
+}
+
+void LLPanelEnvironmentInfo::onAltSliderCallback(LLUICtrl *cntrl, const LLSD &data)
+{
+ LLMultiSliderCtrl *sld = (LLMultiSliderCtrl *)cntrl;
+ std::string sld_name = sld->getCurSlider();
+ 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 = 1;
+ while (iter2 != end)
+ {
+ if (iter->second.mAltitude > iter2->second.mAltitude)
+ {
+ new_index++;
+ }
+ iter2++;
+ }
+ iter->second.mAltitudeIndex = new_index;
+ updateAltLabel(alt_labels[iter->second.mLabelIndex], iter->second.mAltitudeIndex + 1, iter->second.mAltitude);
+ iter++;
+ }
+
+ readjustAltLabels();
+ setDirtyFlag(DIRTY_FLAG_ALTITUDES);
+}
+
+void LLPanelEnvironmentInfo::onBtnApply()
+{
+ doApply();
+}
+
+void LLPanelEnvironmentInfo::onBtnReset()
+{
+ mCurrentEnvironment.reset();
+ refreshFromSource();
+}
+
+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_REGION)
+ (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);
+ else
+ dayeditor->setEditDefaultDayCycle();
+}
+
+void LLPanelEnvironmentInfo::onBtnSelect()
+{
+ LLFloaterSettingsPicker *picker = getSettingsPicker();
+ if (picker)
+ {
+ picker->setSettingsFilter(LLSettingsType::ST_NONE);
+ picker->setSettingsAssetId((mCurrentEnvironment && mCurrentEnvironment->mDayCycle) ? mCurrentEnvironment->mDayCycle->getAssetId() : LLUUID::null);
+ picker->openFloater();
+ picker->setFocus(TRUE);
+ }
+}
+
+
+void LLPanelEnvironmentInfo::doApply()
+{
+ S32 parcel_id = getParcelId();
+
+ if (getIsDirtyFlag(DIRTY_FLAG_MASK))
+ {
+ LLHandle<LLPanel> that_h = getHandle();
+
+ S32 rdo_selection = getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->getSelectedIndex();
+
+ if (rdo_selection == 0)
+ {
+ LLEnvironment::instance().resetParcel(parcel_id,
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+ else if (rdo_selection == 1)
+ {
+ LLEnvironment::instance().updateParcel(parcel_id,
+ mCurrentEnvironment->mDayCycle->getAssetId(), mCurrentEnvironment->mDayLength.value(), mCurrentEnvironment->mDayOffset.value(),
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+ else
+ {
+ LLEnvironment::instance().updateParcel(parcel_id,
+ mCurrentEnvironment->mDayCycle, mCurrentEnvironment->mDayLength.value(), mCurrentEnvironment->mDayOffset.value(),
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+
+ // Todo: save altitudes once LLEnvironment::setRegionAltitudes() gets implemented
+
+ setControlsEnabled(false);
+ }
+}
+
+
+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 asset_id)
+{
+ LLSettingsVOBase::getSettingsAsset(asset_id, [this](LLUUID, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) {
+ if (status)
+ return;
+ onPickerAssetDownloaded(settings);
+ });
+}
+
+void LLPanelEnvironmentInfo::onEditCommitted(LLSettingsDay::ptr_t newday)
+{
+ if (!newday)
+ {
+ LL_WARNS("ENVPANEL") << "Editor committed an empty day. Do nothing." << LL_ENDL;
+ return;
+ }
+ size_t newhash(newday->getHash());
+ size_t oldhash((mCurrentEnvironment->mDayCycle) ? mCurrentEnvironment->mDayCycle->getHash() : 0);
+
+ if (newhash != oldhash)
+ {
+ mCurrentEnvironment->mDayCycle = newday;
+ setDirtyFlag(DIRTY_FLAG_DAYCYCLE);
+ refresh();
+ }
+}
+
+void LLPanelEnvironmentInfo::onEnvironmentChanged(LLEnvironment::EnvSelection_t env)
+{
+ if ((isRegion() && (env == LLEnvironment::ENV_REGION)) ||
+ ((env == LLEnvironment::ENV_PARCEL) && (getParcelId() == LLViewerParcelMgr::instance().getAgentParcelId())))
+ {
+ mCurrentEnvironment.reset();
+ refreshFromSource();
+ }
+}
+
+
+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);
+ refresh();
+}
+
+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);
+}
diff --git a/indra/newview/llpanelenvironment.h b/indra/newview/llpanelenvironment.h
new file mode 100644
index 0000000000..9bc0b9df9c
--- /dev/null
+++ b/indra/newview/llpanelenvironment.h
@@ -0,0 +1,178 @@
+/**
+ * @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"
+
+class LLViewerRegion;
+
+class LLPanelEnvironmentInfo : public LLPanel
+{
+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 RDG_ENVIRONMENT_SELECT;
+ static const std::string RDO_USEDEFAULT;
+ static const std::string RDO_USEINV;
+ static const std::string RDO_USECUSTOM;
+ static const std::string EDT_INVNAME;
+ static const std::string BTN_SELECTINV;
+ static const std::string BTN_EDIT;
+ 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 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 TXT_DISABLED;
+
+ static const std::string STR_LABEL_USEDEFAULT;
+ static const std::string STR_LABEL_USEREGION;
+ static const std::string STR_LABEL_UNKNOWNINV;
+ 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 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 setApplyProgress(bool started);
+ 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_name, U32 sky_index, F32 alt_value);
+ void readjustAltLabels();
+
+ void onSwitchDefaultSelection();
+ void onSldDayLengthChanged(F32 value);
+ void onSldDayOffsetChanged(F32 value);
+ void onAltSliderCallback(LLUICtrl *cntrl, const LLSD &data);
+ void onBtnApply();
+ void onBtnReset();
+ void onBtnEdit();
+ void onBtnSelect();
+
+ virtual void doApply();
+
+ void udpateApparentTimeOfDay();
+
+ void onPickerCommitted(LLUUID asset_id);
+ void onEditCommitted(LLSettingsDay::ptr_t newday);
+ 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 void refreshFromSource() = 0;
+
+ std::string getInventoryNameForAssetId(LLUUID asset_id);
+
+ 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);
+
+ class AltitudeData
+ {
+ public:
+ AltitudeData() :
+ mAltitudeIndex(0), mLabelIndex(0), mAltitude(0)
+ {}
+ AltitudeData(U32 altitude_index, U32 label_index, F32 altitude) :
+ mAltitudeIndex(altitude_index), mLabelIndex(label_index), mAltitude(altitude)
+ {}
+
+ U32 mAltitudeIndex;
+ U32 mLabelIndex;
+ F32 mAltitude;
+ };
+ typedef std::map<std::string, AltitudeData> altitudes_data_t;
+ altitudes_data_t mAltitudes;
+
+
+
+private:
+ static void onIdlePlay(void *);
+
+ typedef boost::signals2::connection connection_t;
+
+ connection_t mCommitConnection;
+ connection_t mChangeMonitor;
+ LLHandle<LLFloater> mSettingsFloater;
+ LLHandle<LLFloater> mEditFloater;
+ S32 mDirtyFlag;
+ bool mCrossRegion;
+ bool mNoSelection;
+ bool mNoEnvironment;
+};
+#endif // LL_LLPANELEXPERIENCES_H
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index ce6834b4b3..7373c7412c 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())
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index db9d61c637..b5e24b6efb 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -58,6 +58,7 @@
#include "llsidepanelinventory.h"
#include "llfolderview.h"
#include "llradiogroup.h"
+#include "llenvironment.h"
const std::string FILTERS_FILENAME("filters.xml");
@@ -128,6 +129,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);
}
@@ -905,6 +909,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);
@@ -997,6 +1002,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
@@ -1114,7 +1125,8 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
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_snapshot")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_settings")->setValue(TRUE);
}
//static
@@ -1135,6 +1147,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);
}
//////////////////////////////////////////////////////////////////////////////////
@@ -1546,5 +1559,10 @@ void LLPanelMainInventory::setUploadCostIfNeeded()
}
}
+bool LLPanelMainInventory::hasSettingsInventory()
+{
+ return LLEnvironment::instance().isInventoryEnabled();
+}
+
// List Commands //
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 732a3b04e3..a6bdee233d 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -161,6 +161,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.
*/
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index cd1875e995..35c5407e6c 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)
{
@@ -1208,6 +1210,34 @@ void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
///----------------------------------------------------------------------------
+/// 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
//----------------------------------------------------------------------------
@@ -1293,6 +1323,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;
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 5f413fc3c0..3d3dccee0b 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);
@@ -642,7 +642,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;
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/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 787bd68e58..70ce275734 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -1091,7 +1091,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 +1111,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;
}
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index d4a8bbdf45..fec16998d6 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -508,14 +508,19 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
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;
}
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 9431914ba3..2773e02598 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"
@@ -1710,9 +1709,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);
}
@@ -2260,11 +2261,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/llsettingspicker.cpp b/indra/newview/llsettingspicker.cpp
new file mode 100644
index 0000000000..f72c7c5dcf
--- /dev/null
+++ b/indra/newview/llsettingspicker.cpp
@@ -0,0 +1,412 @@
+/**
+* @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 "llfiltereditor.h"
+#include "llfolderviewmodel.h"
+#include "llinventory.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.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 PNL_INVENTORY("pnl_inventory");
+ const std::string CHK_SHOWFOLDERS("chk_showfolders");
+ const std::string BTN_SELECT("btn_select");
+ const std::string BTN_CANCEL("btn_cancel");
+
+ const F32 CONTEXT_CONE_IN_ALPHA(0.0f);
+ const F32 CONTEXT_CONE_OUT_ALPHA(1.0f);
+ const F32 CONTEXT_FADE_TIME(0.08f);
+}
+//=========================================================================
+
+LLFloaterSettingsPicker::LLFloaterSettingsPicker(LLView * owner, LLUUID initial_asset_id, const std::string &label, const LLSD &params):
+ LLFloater(params),
+ mOwnerHandle(),
+ mLabel(label),
+ mActive(true),
+ mContextConeOpacity(0.0f),
+ mSettingAssetID(initial_asset_id),
+ mImmediateFilterPermMask(PERM_NONE)
+{
+ mOwnerHandle = owner->getHandle();
+
+ buildFromFile(FLOATER_DEFINITION_XML);
+ setCanMinimize(FALSE);
+}
+
+
+LLFloaterSettingsPicker::~LLFloaterSettingsPicker()
+{
+
+}
+
+//-------------------------------------------------------------------------
+BOOL LLFloaterSettingsPicker::postBuild()
+{
+ if (!LLFloater::postBuild())
+ return FALSE;
+
+ if (!mLabel.empty())
+ {
+ std::string pick = getString("pick title");
+
+ setTitle(pick + mLabel);
+ }
+
+// childSetCommitCallback(CHK_SHOWFOLDERS, onShowFolders, this);
+ getChildView(CHK_SHOWFOLDERS)->setVisible(FALSE);
+
+ 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);
+
+ // 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 (!mSettingAssetID.isNull())
+ {
+ mInventoryPanel->setSelection(findItemID(mSettingAssetID, false), TAKE_FOCUS_NO);
+ }
+ }
+
+ mNoCopySettingsSelected = FALSE;
+
+ childSetAction(BTN_CANCEL, [this](LLUICtrl*, const LLSD& param){ onButtonCancel(); });
+ childSetAction(BTN_SELECT, [this](LLUICtrl*, const LLSD& param){ onButtonSelect(); });
+
+ // 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);
+ }
+}
+
+void LLFloaterSettingsPicker::setValue(const LLSD& value)
+{
+ mSettingAssetID = value.asUUID();
+}
+
+LLSD LLFloaterSettingsPicker::getValue() const
+{
+ return LLSD(mSettingAssetID);
+}
+
+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::draw()
+{
+ LLView *owner = mOwnerHandle.get();
+ if (owner)
+ {
+ // draw cone of context pointing back to texture swatch
+ LLRect owner_rect;
+ owner->localRectToOtherView(owner->getLocalRect(), &owner_rect, this);
+ LLRect local_rect = getLocalRect();
+ if (gFocusMgr.childHasKeyboardFocus(this) && owner->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));
+ }
+
+ 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)
+{
+ if (items.size())
+ {
+ LLFolderViewItem* first_item = items.front();
+ LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
+ mNoCopySettingsSelected = false;
+ if (itemp)
+ {
+// if (!mChangeIDSignal.empty())
+// {
+// mChangeIDSignal(itemp);
+// }
+ if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ mNoCopySettingsSelected = true;
+ }
+ setSettingsAssetId(itemp->getAssetUUID(), false);
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
+ if (user_action)
+ {
+ mChangeIDSignal(mSettingAssetID);
+ }
+ }
+ }
+}
+
+void LLFloaterSettingsPicker::onButtonCancel()
+{
+ closeFloater();
+}
+
+void LLFloaterSettingsPicker::onButtonSelect()
+{
+ if (mCommitSignal)
+ (*mCommitSignal)(this, LLSD(mSettingAssetID));
+ closeFloater();
+}
+
+BOOL LLFloaterSettingsPicker::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ if (mSettingAssetID.notNull()
+ && mInventoryPanel)
+ {
+ LLUUID item_id = findItemID(mSettingAssetID, FALSE);
+ S32 inventory_x = x - mInventoryPanel->getRect().mLeft;
+ S32 inventory_y = y - mInventoryPanel->getRect().mBottom;
+ if (item_id.notNull()
+ && mInventoryPanel->parentPointInView(inventory_x, inventory_y))
+ {
+ // make sure item (not folder) is selected
+ LLFolderViewItem* item_viewp = mInventoryPanel->getItemByID(item_id);
+ if (item_viewp && item_viewp->isSelected())
+ {
+ LLRect target_rect;
+ item_viewp->localRectToOtherView(item_viewp->getLocalRect(), &target_rect, this);
+ if (target_rect.pointInRect(x, y))
+ {
+ // Quick-apply
+ if (mCommitSignal)
+ (*mCommitSignal)(this, LLSD(mSettingAssetID));
+ closeFloater();
+ return TRUE;
+ }
+ }
+ }
+ }
+ return LLFloater::handleDoubleClick(x, y, mask);
+}
+
+//=========================================================================
+void LLFloaterSettingsPicker::setActive(bool active)
+{
+ mActive = active;
+}
+
+void LLFloaterSettingsPicker::setSettingsAssetId(const LLUUID &settings_id, bool set_selection)
+{
+ if (mSettingAssetID != settings_id && mActive)
+ {
+ mNoCopySettingsSelected = false;
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+ mSettingAssetID = settings_id;
+ LLUUID item_id = findItemID(mSettingAssetID, FALSE);
+ if (item_id.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..7fcc7fd4a7
--- /dev/null
+++ b/indra/newview/llsettingspicker.h
@@ -0,0 +1,126 @@
+/**
+ * @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 <boost/signals2.hpp>
+
+//=========================================================================
+class LLFilterEditor;
+class LLInventoryPanel;
+
+//=========================================================================
+class LLFloaterSettingsPicker : public LLFloater
+{
+public:
+ typedef std::function<void (LLUUID id)> commit_callback_t;
+ typedef std::function<void()> close_callback_t;
+ typedef std::function<void(const LLUUID& asset_id)> id_changed_callback_t;
+
+ LLFloaterSettingsPicker(LLView * owner, LLUUID setting_asset_id, const std::string &label, 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 setSettingsAssetId(const LLUUID &settings_id, bool set_selection = true);
+ LLUUID getSettingsAssetId() const { return mSettingAssetID; }
+
+ void setDefaultSettingsAssetID(LLUUID id) { mDefaultSettingsAssetID = id; }
+ LLUUID getDefaultSettingsAssetID() const { return mDefaultSettingsAssetID; }
+
+ void setSettingsFilter(LLSettingsType::type_e type);
+ LLSettingsType::type_e getSettingsFilter() const { return mSettingsType; }
+
+ // Takes a UUID, wraps get/setImageAssetID
+ virtual void setValue(const LLSD& value) override;
+ virtual LLSD getValue() const override;
+
+ 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;
+ }
+
+ 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();
+ }
+
+ 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);
+ void onButtonCancel();
+ void onButtonSelect();
+ virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override;
+
+
+ LLHandle<LLView> mOwnerHandle;
+ std::string mLabel;
+ LLUUID mSettingAssetID;
+ LLUUID mDefaultSettingsAssetID;
+
+ LLFilterEditor * mFilterEdit;
+ LLInventoryPanel * mInventoryPanel;
+ LLSettingsType::type_e mSettingsType;
+
+ F32 mContextConeOpacity;
+ PermissionMask mImmediateFilterPermMask;
+// PermissionMask mDnDFilterPermMask;
+// PermissionMask mNonImmediateFilterPermMask;
+
+ bool mActive;
+ bool mNoCopySettingsSelected;
+
+ LLSaveFolderState mSavedFolderState;
+
+// boost::signals2::signal<void(LLUUID id)> mCommitSignal;
+ boost::signals2::signal<void()> mCloseSignal;
+ boost::signals2::signal<void(const LLUUID& asset_id)> mChangeIDSignal;
+};
+
+#endif // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
new file mode 100644
index 0000000000..8d66004ddb
--- /dev/null
+++ b/indra/newview/llsettingsvo.cpp
@@ -0,0 +1,1338 @@
+/**
+* @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"
+
+#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);
+
+ //-------------------------------------------------------------------------
+ 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)
+{
+ LLTransactionID tid;
+ U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
+
+ 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(), nextOwnerPerm, cb);
+}
+
+void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback)
+{
+ 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;
+ LLViewerInventoryItem *pitem = gInventory.getItem(inventoryId);
+
+ 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 );
+
+#if 0
+ std::string exprtFile = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + newAssetId.asString() + ".llsd";
+
+ LLSettingsVOBase::exportFile(psettings, exprtFile, LLSDSerialize::LLSD_NOTATION);
+
+ LL_WARNS("LAPRAS") << "SETTINGS File written as: '" << exprtFile << "'" << LL_ENDL;
+#endif
+}
+
+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
+ {
+ LL_WARNS("LAPRAS") << "Setting asset ID to " << asset_id << LL_ENDL;
+ settings->setAssetId(asset_id);
+ }
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "Error retrieving asset " << asset_id << ". Status code=" << status << "(" << LLAssetStorage::getErrorString(status) << ") ext_status=" << 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 &legacy)
+{
+
+ LLSD newsettings = LLSettingsSky::translateLegacySettings(legacy);
+
+ newsettings[SETTING_NAME] = name;
+
+ LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
+ LLSD results = LLSettingsBase::settingValidation(newsettings, 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>(newsettings);
+
+#ifdef VERIFY_LEGACY_CONVERSION
+ LLSD oldsettings = LLSettingsVOSky::convertToLegacy(skyp, isAdvanced());
+
+ if (!llsd_equals(legacy, oldsettings))
+ {
+ LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n"
+ << "Old: " << legacy
+ << "new: " << oldsettings << LL_ENDL;
+ }
+
+#endif
+
+ return skyp;
+}
+
+LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPresetFile(const std::string &name, const std::string &path)
+{
+ LLSD legacy_data = read_legacy_preset_data(name, path);
+
+ if (!legacy_data)
+ {
+ LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
+ return ptr_t();
+ }
+
+ return buildFromLegacyPreset(name, legacy_data);
+}
+
+
+LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky()
+{
+ static LLSD default_settings;
+
+ if (!default_settings.size())
+ {
+ default_settings = LLSettingsSky::defaults();
+
+ default_settings[SETTING_NAME] = std::string("_default_");
+
+ 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();
+
+ 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);
+ return skyp;
+}
+
+void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings)
+{
+ // These will need to be inferred from new settings' density profiles
+ if (settings.has(SETTING_LEGACY_HAZE))
+ {
+ LLSD legacyhaze = settings[SETTING_LEGACY_HAZE];
+ legacy[SETTING_AMBIENT] = ensure_array_4(legacyhaze[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];
+ legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f);
+
+ LLQuaternion sunquat = psky->getSunRotation();
+
+ F32 roll;
+ F32 pitch;
+ F32 yaw;
+
+ // get euler angles in right-handed X right, Y up, Z at
+ sunquat.getEulerAngles(&roll, &pitch, &yaw);
+
+ legacy[SETTING_LEGACY_EAST_ANGLE] = yaw;
+ legacy[SETTING_LEGACY_SUN_ANGLE] = -pitch;
+
+ return legacy;
+}
+
+//-------------------------------------------------------------------------
+void LLSettingsVOSky::updateSettings()
+{
+ LLSettingsSky::updateSettings();
+ LLVector3 sun_direction = getSunDirection();
+ LLVector3 moon_direction = getMoonDirection();
+
+ F32 dp = getLightDirection() * LLVector3(0.0f, 0.0f, 1.0f);
+ if (dp < 0)
+ {
+ dp = 0;
+ }
+ dp = llmax(dp, 0.1f);
+
+ // 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);
+ mSceneLightStrength = 2.0f * (1.0f + 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)
+{
+ LLGLSLShader *shader = (LLGLSLShader *)ptarget;
+
+ LLVector4 light_direction = LLEnvironment::instance().getClampedSunNorm();
+
+ 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);
+
+ LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
+ vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta());
+ shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV);
+ }
+
+ shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
+ shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0);
+}
+
+LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
+{
+ static parammapping_t param_map;
+
+ if (param_map.empty())
+ {
+// LEGACY_ATMOSPHERICS
+ param_map[SETTING_AMBIENT] = LLShaderMgr::AMBIENT;
+ param_map[SETTING_BLUE_DENSITY] = LLShaderMgr::BLUE_DENSITY;
+ param_map[SETTING_BLUE_HORIZON] = LLShaderMgr::BLUE_HORIZON;
+ param_map[SETTING_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY;
+ param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON;
+ param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER;
+ param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER;
+
+ param_map[SETTING_CLOUD_COLOR] = LLShaderMgr::CLOUD_COLOR;
+ param_map[SETTING_CLOUD_POS_DENSITY2] = LLShaderMgr::CLOUD_POS_DENSITY2;
+ param_map[SETTING_CLOUD_SCALE] = LLShaderMgr::CLOUD_SCALE;
+ param_map[SETTING_CLOUD_SHADOW] = LLShaderMgr::CLOUD_SHADOW;
+ param_map[SETTING_GLOW] = LLShaderMgr::GLOW;
+ param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y;
+ param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR;
+
+// 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 &legacy)
+{
+ LLSD newsettings(LLSettingsWater::translateLegacySettings(legacy));
+
+ newsettings[SETTING_NAME] = name;
+ LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
+ LLSD results = LLSettingsWater::settingValidation(newsettings, 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>(newsettings);
+
+#ifdef VERIFY_LEGACY_CONVERSION
+ LLSD oldsettings = LLSettingsVOWater::convertToLegacy(waterp);
+
+ if (!llsd_equals(legacy, oldsettings))
+ {
+ LL_WARNS("WATER") << "Conversion to/from legacy does not match!\n"
+ << "Old: " << legacy
+ << "new: " << oldsettings << LL_ENDL;
+ }
+
+#endif
+ return waterp;
+}
+
+LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPresetFile(const std::string &name, const std::string &path)
+{
+ LLSD legacy_data = read_legacy_preset_data(name, path);
+
+ if (!legacy_data)
+ {
+ LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
+ return ptr_t();
+ }
+
+ return buildFromLegacyPreset(name, legacy_data);
+}
+
+
+LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater()
+{
+ static LLSD default_settings;
+
+ if (!default_settings.size())
+ {
+ default_settings = LLSettingsWater::defaults();
+
+ default_settings[SETTING_NAME] = std::string("_default_");
+
+ 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();
+ 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);
+
+ return waterp;
+}
+
+LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater)
+{
+ LLSD legacy(LLSD::emptyMap());
+ LLSD settings = pwater->getSettings();
+
+ legacy[SETTING_LEGACY_BLUR_MULTIPILER] = settings[SETTING_BLUR_MULTIPILER];
+ 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];
+
+ //_WARNS("LAPRAS") << "Legacy water: " << legacy << LL_ENDL;
+ return legacy;
+}
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+void LLSettingsVOWater::applySpecial(void *ptarget)
+{
+ LLGLSLShader *shader = (LLGLSLShader *)ptarget;
+
+ if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
+ {
+ //transform water plane to eye space
+ glh::vec3f norm(0.f, 0.f, 1.f);
+ glh::vec3f p(0.f, 0.f, LLEnvironment::instance().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);
+
+ 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 = LLEnvironment::instance().getClampedLightNorm();
+
+ F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
+
+ shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS);
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ 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);
+ shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0);
+ }
+}
+
+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())
+ {
+ param_map[SETTING_FOG_COLOR] = LLShaderMgr::WATER_FOGCOLOR;
+ param_map[SETTING_FOG_DENSITY] = LLShaderMgr::WATER_FOGDENSITY;
+ }
+ 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 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);
+ if (pwater)
+ 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);
+ if (psky)
+ 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())
+ {
+ 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 legacy_data = read_legacy_preset_data(name, path);
+
+ if (!legacy_data)
+ {
+ LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
+ return ptr_t();
+ }
+
+ return buildFromLegacyPreset(name, path, legacy_data);
+}
+
+
+
+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" );
+
+ LL_WARNS("LAPRAS") << "newsettings=" << newsettings << LL_ENDL;
+
+ 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] = std::string("_default_");
+
+ 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);
+
+ 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++;
+ }
+ }
+ 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()) );
+ }
+ //_WARNS("LAPRAS") << "Cycle created with " << llsdcycle.size() << "entries: " << llsdcycle << LL_ENDL;
+
+ 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;
+ }
+
+ //_WARNS("LAPRAS") << "Sky map with " << llsdskylist.size() << " entries created: " << llsdskylist << LL_ENDL;
+
+ 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)
+ {
+ 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)
+ {
+ LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL;
+ return LLSD();
+ }
+ }
+ }
+
+ LLSD params_data;
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED);
+ xml_file.close();
+
+ return params_data;
+ }
+}
diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h
new file mode 100644
index 0000000000..0e8312b849
--- /dev/null
+++ b/indra/newview/llsettingsvo.h
@@ -0,0 +1,182 @@
+/**
+* @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 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 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);
+ static ptr_t buildDefaultSky();
+ virtual ptr_t buildClone() const SETTINGS_OVERRIDE;
+
+ static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path);
+
+ static LLSD convertToLegacy(const ptr_t &, bool isAdvanced);
+
+ bool isAdvanced() const { return m_isAdvanced; }
+
+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 *) 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);
+ static ptr_t buildDefaultWater();
+ virtual ptr_t buildClone() const SETTINGS_OVERRIDE;
+
+ static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path);
+
+ static LLSD convertToLegacy(const ptr_t &);
+protected:
+ LLSettingsVOWater();
+
+ virtual void updateSettings() override;
+ virtual void applySpecial(void *) 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;
+
+ 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);
+ static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path);
+ 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/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 2503e2a5e2..d7c2ecb758 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -301,6 +301,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);
@@ -630,14 +631,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);
@@ -656,6 +657,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/llsky.cpp b/indra/newview/llsky.cpp
index 3ef89ba920..0740878901 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 "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();
+ if(mVOSkyp.notNull())
+ {
+ mVOSkyp->setSunScale(sun_scale);
}
- else if (mOverrideSimSunPosition && !override)
- {
- setSunDirection(mLastSunDirection, LLVector3::zero);
- }
- 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)
+void LLSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
{
- mSunTargDir = sun_direction;
-}
-
-
-LLVector3 LLSky::getSunDirection() const
-{
- 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
+void LLSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next)
{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getSunAmbientColor());
- }
- else
- {
- return LLColor4(0.f, 0.f, 0.f, 1.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setBloomTextures(bloom_texture, bloom_texture_next);
}
}
-
-LLColor4 LLSky::getMoonDiffuseColor() const
+void LLSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_direction, const LLVector3 &moon_direction)
{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getMoonDiffuseColor());
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
}
}
-LLColor4 LLSky::getMoonAmbientColor() const
+void LLSky::setSunDirectionCFR(const LLVector3 &sun_direction)
{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getMoonAmbientColor());
- }
- else
- {
- return LLColor4(0.f, 0.f, 0.f, 0.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setSunDirectionCFR(sun_direction);
}
}
-
-LLColor4 LLSky::getTotalAmbientColor() const
+void LLSky::setMoonDirectionCFR(const LLVector3 &moon_direction)
{
- if (mVOSkyp)
- {
- return mVOSkyp->getTotalAmbientColor();
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setMoonDirectionCFR(moon_direction);
}
}
-
-BOOL LLSky::sunUp() const
-{
- if (mVOSkyp)
- {
- return mVOSkyp->isSunUp();
- }
- else
- {
- return TRUE;
- }
-}
-
-
-LLColor4U LLSky::getFadeColor() const
-{
- if (mVOSkyp)
- {
- return mVOSkyp->getFadeColor();
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
- }
-}
-
-
//////////////////////////////////////////////////////////////////////
// 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);
+ gPipeline.createObject(mVOGroundp.get());
- 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));
- }
-
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));
mUpdatedThisFrame = TRUE;
}
@@ -361,49 +234,16 @@ void LLSky::setWind(const LLVector3& average_wind)
}
}
-
-void LLSky::propagateHeavenlyBodies(F32 dt)
-{
- if (!mOverrideSimSunPosition)
- {
- 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());
- }
- }
- }
-}
-
-F32 LLSky::getSunPhase() const
-{
- return mSunPhase;
-}
-
-void LLSky::setSunPhase(const F32 phase)
-{
- mSunPhase = phase;
-}
-
//////////////////////////////////////////////////////////////////////
// Private Methods
//////////////////////////////////////////////////////////////////////
-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..e3cc567888 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);
+
+ void setSunScale(F32 sun_scale);
+ void setMoonScale(F32 moon_scale);
- LLColor4 getFogColor() const;
+ 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,18 +80,6 @@ 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();
@@ -94,25 +87,11 @@ public:
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/llstartup.cpp b/indra/newview/llstartup.cpp
index cc02642203..831b9e2d2a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -180,8 +180,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"
@@ -197,6 +195,8 @@
#include "llexperiencelog.h"
#include "llcleanup.h"
+#include "llenvironment.h"
+
#include "llstacktrace.h"
#if LL_WINDOWS
@@ -333,7 +333,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
@@ -1466,8 +1465,8 @@ bool idle_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLEnvManagerNew::getInstance()->usePrefs(); // Load all presets and settings
- gSky.init(initial_sun_direction);
+ LLEnvironment::instance().loadPreferences();
+ gSky.init();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -3507,26 +3506,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"];
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 0f38cca56f..02fec1eb75 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())
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index 6c9155be85..ee757f2566 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -107,8 +107,15 @@ 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("SkySunDefaultPosition", LLViewerCamera::getInstance()->getAtAxis());
}
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/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index 50131682e7..cefe215431 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -69,14 +69,14 @@ 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);
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,7 +86,7 @@ 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);
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..2544f75926 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -487,7 +487,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType:
mTaskId(LLUUID::null),
mContents(buffer),
mInvnFinishFn(finish),
- mTaskFinishFn(NULL),
+ mTaskFinishFn(nullptr),
mStoredToVFS(false)
{
setItemId(itemId);
@@ -501,7 +501,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LL
mTaskId(LLUUID::null),
mContents(),
mInvnFinishFn(finish),
- mTaskFinishFn(NULL),
+ mTaskFinishFn(nullptr),
mStoredToVFS(false)
{
setItemId(itemId);
@@ -534,7 +534,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemI
mTaskUpload(true),
mTaskId(taskId),
mContents(buffer),
- mInvnFinishFn(NULL),
+ mInvnFinishFn(nullptr),
mTaskFinishFn(finish),
mStoredToVFS(false)
{
@@ -739,6 +739,10 @@ 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();
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
index ee1806b782..4241c22c3e 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,
@@ -169,8 +169,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 88984d518a..ebc55fa0dd 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -410,6 +410,17 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
return true;
}
+static bool handleRenderUseAdvancedAtmosphericsChanged(const LLSD& newvalue)
+{
+ if (gPipeline.isInit())
+ {
+ LLPipeline::refreshCachedSettings();
+ // Need to reload shaders when changing atmospherics implementations...
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+ return true;
+}
+
// This looks a great deal like handleRenderDeferredChanged because
// Advanced Lighting (Materials) implies bumps and shiny so disabling
// bumps should further disable that feature.
@@ -644,6 +655,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
+ gSavedSettings.getControl("RenderUseAdvancedAtmospherics")->getSignal()->connect(boost::bind(&handleRenderUseAdvancedAtmosphericsChanged, _2));
gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 86a9e7e2ad..82120db53e 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;
@@ -200,8 +200,7 @@ void display_update_camera()
gViewerWindow->setup3DRender();
// update all the sky/atmospheric/water settings
- LLWLParamManager::getInstance()->update(LLViewerCamera::getInstance());
- LLWaterParamManager::getInstance()->update(LLViewerCamera::getInstance());
+ LLEnvironment::instance().update(LLViewerCamera::getInstance());
// Update land visibility too
LLWorld::getInstance()->setLandFarClip(final_far);
@@ -730,8 +729,8 @@ 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() ;
@@ -740,8 +739,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
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);
@@ -921,7 +920,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.mScreen.bindTarget();
if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
{
- const LLColor4 &col = LLDrawPoolWater::sWaterFogColor;
+ const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
}
gPipeline.mScreen.clear();
@@ -1079,8 +1078,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);
@@ -1172,8 +1171,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()
@@ -1255,11 +1254,11 @@ 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;
}
@@ -1267,13 +1266,13 @@ void render_ui(F32 zoom_factor, int subfield)
{
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())
@@ -1336,7 +1335,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/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 0ebacddd9b..feac071cac 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -55,18 +55,16 @@
#include "llfloaterchatvoicevolume.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
-#include "llfloaterdeleteenvpreset.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
#include "llfloatereditdaycycle.h"
-#include "llfloatereditsky.h"
-#include "llfloatereditwater.h"
-#include "llfloaterenvironmentsettings.h"
+#include "llfloatereditextdaycycle.h"
#include "llfloaterexperienceprofile.h"
#include "llfloaterexperiences.h"
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
#include "llfloaterfacebook.h"
+#include "llfloaterfixedenvironment.h"
#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
#include "llfloatergesture.h"
@@ -90,6 +88,7 @@
#include "llfloatermediasettings.h"
#include "llfloatermemleak.h"
#include "llfloatermodelpreview.h"
+#include "llfloatermyenvironment.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
#include "llfloaternotificationstabbed.h"
@@ -221,12 +220,15 @@ void LLViewerFloaterReg::registerFloaters()
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_fixed_environmentent", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironment>);
+
+ 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>);
LLFloaterReg::add("experience_profile", "floater_experienceprofile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperienceProfile>);
@@ -250,6 +252,9 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);
LLFloaterReg::add("item_properties", "floater_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterItemProperties>);
+
+// LLFloaterReg::add("floater_settings_picker", "floater_settings_picker.xml" , (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterItemProperties>);
+
LLInspectAvatarUtil::registerFloater();
LLInspectGroupUtil::registerFloater();
LLInspectObjectUtil::registerFloater();
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/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 1ab7ec0156..e4d3d73a3e 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&) {}
@@ -1097,7 +1098,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)
{
@@ -1132,7 +1133,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);
@@ -1146,9 +1147,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,
@@ -1700,7 +1728,7 @@ void create_new_item(const std::string& name,
desc,
asset_type,
inv_type,
- NOT_WEARABLE,
+ NO_INV_SUBTYPE,
next_owner_perm,
cb);
}
@@ -1793,6 +1821,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.
@@ -1973,6 +2027,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..d537b28682 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.
@@ -295,7 +299,7 @@ public:
// virtual
void fire(const LLUUID& item_id)
-{
+ {
mFireFunc(item_id);
}
@@ -336,17 +340,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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ec851ddaf9..26f0ec7905 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -51,9 +51,8 @@
#include "llagentpilot.h"
#include "llcompilequeue.h"
#include "llconsole.h"
-#include "lldaycyclemanager.h"
#include "lldebugview.h"
-#include "llenvmanager.h"
+#include "llenvironment.h"
#include "llfacebookconnect.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
@@ -121,9 +120,6 @@
#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"
@@ -136,6 +132,7 @@
#include "boost/unordered_map.hpp"
#include <boost/regex.hpp>
#include "llcleanup.h"
+#include "llviewershadermgr.h"
using namespace LLAvatarAppearanceDefines;
@@ -8414,42 +8411,63 @@ class LLWorldEnvSettings : public view_listener_t
{
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::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().updateEnvironment();
}
-
- if (tod == "sunrise")
+ else if (event_name == "noon")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Sunrise");
- }
- else if (tod == "noon")
- {
- LLEnvManagerNew::instance().setUseSkyPreset("Midday");
- }
- else if (tod == "sunset")
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().updateEnvironment();
+ }
+ else if (event_name == "sunset")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Sunset");
- }
- else if (tod == "midnight")
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().updateEnvironment();
+ }
+ else if (event_name == "midnight")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Midnight");
- }
- else
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().updateEnvironment();
+ }
+ else if (event_name == "region")
{
- 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);
- }
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().updateEnvironment();
+ }
+ else if (event_name == "pause_clouds")
+ {
+ if (LLEnvironment::instance().isCloudScrollPaused())
+ LLEnvironment::instance().resumeCloudScroll();
+ else
+ LLEnvironment::instance().pauseCloudScroll();
+ }
+ else if (event_name == "my_environs")
+ {
+ LLUUID asset_id;
+ LLSettingsBase::ptr_t cur(LLEnvironment::instance().getCurrentDay());
+ if (!cur)
+ {
+ cur = LLEnvironment::instance().getCurrentSky();
+ }
+
+ if (cur)
+ {
+ asset_id = cur->getAssetId();
+ }
+
+ LLFloaterReg::showInstance("my_environments", LLSDMap("asset_id", LLSD::UUID(asset_id)));
+ }
+
return true;
}
};
@@ -8459,39 +8477,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 (event_name == "pause_clouds")
+ {
+ return LLEnvironment::instance().isCloudScrollPaused();
+ }
+
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL);
- if (LLEnvManagerNew::instance().getUseRegionSettings())
+ if (!sky)
{
- return (tod == "region");
+ return (event_name == "region");
}
- if (LLEnvManagerNew::instance().getUseFixedSky())
+ std::string skyname = (sky) ? sky->getName() : "";
+ LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null;
+
+ if (event_name == "sunrise")
{
- if (tod == "sunrise")
- {
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunrise");
- }
- else if (tod == "noon")
- {
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midday");
- }
- else if (tod == "sunset")
- {
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunset");
- }
- else if (tod == "midnight")
- {
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midnight");
- }
- else if (tod == "region")
- {
- return false;
- }
- else
- {
- LL_WARNS() << "Unknown time-of-day item: " << tod << LL_ENDL;
- }
+ result = (skyid == LLEnvironment::KNOWN_SKY_SUNRISE);
+ }
+ else if (event_name == "noon")
+ {
+ result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY);
+ }
+ else if (event_name == "sunset")
+ {
+ result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET);
+ }
+ else if (event_name == "midnight")
+ {
+ result = (skyid == LLEnvironment::KNOWN_SKY_MIDNIGHT);
+ }
+ else if (event_name == "region")
+ {
+ return false;
+ }
+ else
+ {
+ LL_WARNS() << "Unknown time-of-day item: " << event_name << LL_ENDL;
}
return result;
}
@@ -8503,41 +8528,30 @@ class LLWorldEnvPreset : public view_listener_t
{
std::string item = userdata.asString();
+// *LAPRAS* These go away! Keep for the moment.
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
{
@@ -8552,30 +8566,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;
}
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index d2a5578568..bb557fbdaa 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -440,7 +440,7 @@ 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);
}
}
@@ -693,7 +693,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,
@@ -776,7 +776,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 +812,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,
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 0c5bd9ad1d..04cfe270fe 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3758,6 +3758,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;
@@ -3779,12 +3780,11 @@ 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 **)
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 46b3c8f315..374322ac10 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -34,7 +34,6 @@
#include "lltrans.h"
#include "llweb.h"
-
/// key used to store the grid, and the name attribute in the grid data
const std::string GRID_VALUE = "keyname";
/// the value displayed in the grid selector menu, and other human-oriented text
@@ -88,6 +87,13 @@ LLGridManager::LLGridManager()
// an attacker. Don't want someone snagging a password.
std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"grids.xml");
+
+ // fall back to app_settings/grids.xml if it's provided
+ if (!LLFile::isfile(grid_file))
+ {
+ grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
+ "grids.xml");
+ }
LL_DEBUGS("GridManager")<<LL_ENDL;
initialize(grid_file);
@@ -133,6 +139,13 @@ void LLGridManager::initialize(const std::string& grid_file)
"https://my.aditi.lindenlab.com/",
"Aditi");
+ // dump example grid file...
+ //llofstream out_llsd_xml;
+ //std::string default_grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml");
+ //out_llsd_xml.open(default_grid_file.c_str());
+ //LLSDSerialize::toPrettyXML(mGridList, out_llsd_xml);
+ //out_llsd_xml.close();
+
LLSD other_grids;
llifstream llsd_xml;
if (!grid_file.empty())
@@ -484,12 +497,19 @@ void LLGridManager::getLoginURIs(const std::string& grid, std::vector<std::strin
std::string grid_name = getGrid(grid);
if (!grid_name.empty())
{
- for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray();
- llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray();
- llsd_uri++)
- {
- uris.push_back(llsd_uri->asString());
- }
+ if (mGridList[grid_name][GRID_LOGIN_URI_VALUE].isArray())
+ {
+ for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray();
+ llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray();
+ llsd_uri++)
+ {
+ uris.push_back(llsd_uri->asString());
+ }
+ }
+ else
+ {
+ uris.push_back(mGridList[grid_name][GRID_LOGIN_URI_VALUE].asString());
+ }
}
else
{
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 5f0e21db71..7d4d737db4 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1272,7 +1272,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(get_current_projection(), 1);
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/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index f4d14a39fe..c83e27ceed 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -69,6 +69,8 @@
#include "llvieweraudio.h"
#include "llcorehttputil.h"
+#include "llenvironment.h"
+
const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
@@ -645,6 +647,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 +1312,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)
@@ -1460,6 +1494,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;
@@ -1550,6 +1586,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 );
// Actually extract the data.
@@ -1567,6 +1609,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
}
+ bool environment_changed = (parcel->getParcelEnvironmentVersion() != parcel_environment_version);
+
parcel->init(owner_id,
FALSE, FALSE, FALSE,
claim_date, claim_price_per_meter, rent_price_per_meter,
@@ -1592,6 +1636,10 @@ 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(parcel_environment_version);
+ parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override);
+
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)
@@ -1609,9 +1657,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;
@@ -1625,12 +1670,21 @@ 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);
- }
+
+ LL_WARNS("LAPRAS") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL;
+ // Notify anything that wants to know when the agent changes parcels
+ gAgent.changeParcels();
+ }
+ else if (agent_parcel_update)
+ {
+ // updated agent parcel
+ parcel_mgr.mAgentParcel->unpackMessage(msg);
+ if ((LLEnvironment::instance().isExtendedEnvironmentEnabled() && environment_changed))
+ {
+ LL_WARNS("LAPRAS") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL;
+ LLEnvironment::instance().requestParcel(local_id);
+ }
+ }
}
// Handle updating selections, if necessary.
@@ -1811,6 +1865,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
}//if gAudiop
};
+
}
void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 29219843c9..336a3ea228 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,6 +263,7 @@ 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.
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 4f0460da29..263750dee4 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -78,6 +78,7 @@
#include "llcoros.h"
#include "lleventcoro.h"
#include "llcorehttputil.h"
+#include "llsettingsdaycycle.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -2835,6 +2836,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("EnvironmentSettings");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
+ capabilityNames.append("ExtEnvironment");
capabilityNames.append("FacebookConnect");
capabilityNames.append("FlickrConnect");
capabilityNames.append("TwitterConnect");
@@ -2908,7 +2910,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateNotecardTaskInventory");
capabilityNames.append("UpdateScriptAgent");
capabilityNames.append("UpdateScriptTask");
- capabilityNames.append("UploadBakedTexture");
+ capabilityNames.append("UpdateSettingsAgentInventory");
+ capabilityNames.append("UpdateSettingsTaskInventory");
+ capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
capabilityNames.append("ViewerMetrics");
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index ff7647a7e4..3fdcac8917 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -38,13 +38,13 @@
#include "llviewercontrol.h"
#include "pipeline.h"
#include "llworld.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "llsky.h"
#include "llvosky.h"
#include "llrender.h"
#include "lljoint.h"
#include "llskinningutil.h"
+#include "llenvironment.h"
+#include "llatmosphere.h"
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
@@ -93,6 +93,8 @@ LLGLSLShader gDebugProgram;
LLGLSLShader gClipProgram;
LLGLSLShader gDownsampleDepthProgram;
LLGLSLShader gDownsampleDepthRectProgram;
+LLGLSLShader gDownsampleMinMaxDepthRectProgram;
+LLGLSLShader gInscatterRectProgram;
LLGLSLShader gAlphaMaskProgram;
LLGLSLShader gBenchmarkProgram;
@@ -174,7 +176,8 @@ LLGLSLShader gImpostorProgram;
// WindLight shader handles
LLGLSLShader gWLSkyProgram;
LLGLSLShader gWLCloudProgram;
-
+LLGLSLShader gWLSunProgram;
+LLGLSLShader gWLMoonProgram;
// Effects Shaders
LLGLSLShader gGlowProgram;
@@ -230,6 +233,8 @@ LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
LLGLSLShader gDeferredWLSkyProgram;
LLGLSLShader gDeferredWLCloudProgram;
+LLGLSLShader gDeferredWLSunProgram;
+LLGLSLShader gDeferredWLMoonProgram;
LLGLSLShader gDeferredStarProgram;
LLGLSLShader gDeferredFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
@@ -248,6 +253,8 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
//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);
@@ -340,6 +347,8 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
+ mShaderList.push_back(&gDeferredWLMoonProgram);
+ mShaderList.push_back(&gDeferredWLSunProgram);
}
LLViewerShaderMgr::~LLViewerShaderMgr()
@@ -475,7 +484,7 @@ void LLViewerShaderMgr::setShaders()
S32 env_class = 2;
S32 obj_class = 2;
S32 effect_class = 2;
- S32 wl_class = 2;
+ S32 wl_class = 3;
S32 water_class = 2;
S32 deferred_class = 0;
S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
@@ -499,24 +508,23 @@ void LLViewerShaderMgr::setShaders()
{ //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);
}
+ // clamp to WL class 2 if we have disabled adv atmo (class 3)
+ if (!gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"))
+ {
+ wl_class = llmin(wl_class, 2);
+ }
- if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")
- && gSavedSettings.getBOOL("WindLightUseAtmosShaders")))
+ bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
+ bool useWindLightShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ if (!hasWindLightShaders || !useWindLightShaders)
{
// 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())
{
@@ -548,27 +556,67 @@ void LLViewerShaderMgr::setShaders()
if (loaded)
{
loaded = loadShadersWater();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded water shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
+ }
}
if (loaded)
{
loaded = loadShadersWindLight();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded windlight shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL;
+ }
}
if (loaded)
{
loaded = loadShadersEffects();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded effects shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load effects shaders." << LL_ENDL;
+ }
}
if (loaded)
{
loaded = loadShadersInterface();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded interface shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load interface shaders." << LL_ENDL;
+ }
}
if (loaded)
{
loaded = loadTransformShaders();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded transform shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load transform shaders." << LL_ENDL;
+ }
}
if (loaded)
@@ -580,14 +628,10 @@ void LLViewerShaderMgr::setShaders()
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;
- }
+ // cloth is a class3 shader
+ S32 avatar_class = avatar_cloth ? 3 : 1;
+
// Set the actual level
mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
loadShadersAvatar();
@@ -631,6 +675,7 @@ void LLViewerShaderMgr::setShaders()
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;
@@ -639,6 +684,7 @@ void LLViewerShaderMgr::setShaders()
if (gSavedSettings.getBOOL("VertexShaderEnable"))
{ //disable shaders outright and try again
gSavedSettings.setBOOL("VertexShaderEnable", FALSE);
+ LL_WARNS() << "Falling back to no vertex shaders." << LL_ENDL;
reentrance = false;
setShaders();
return;
@@ -648,6 +694,7 @@ void LLViewerShaderMgr::setShaders()
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;
@@ -700,6 +747,8 @@ void LLViewerShaderMgr::unloadShaders()
gClipProgram.unload();
gDownsampleDepthProgram.unload();
gDownsampleDepthRectProgram.unload();
+ gDownsampleMinMaxDepthRectProgram.unload();
+ gInscatterRectProgram.unload();
gBenchmarkProgram.unload();
gAlphaMaskProgram.unload();
gUIProgram.unload();
@@ -786,6 +835,8 @@ void LLViewerShaderMgr::unloadShaders()
gWLSkyProgram.unload();
gWLCloudProgram.unload();
+ gWLSunProgram.unload();
+ gWLMoonProgram.unload();
gPostColorFilterProgram.unload();
gPostNightVisionProgram.unload();
@@ -899,13 +950,17 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
- std::vector<S32> index_channels;
+ 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/atmosphericsHelpersF.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( "environment/encodeNormF.glsl", mVertexShaderLevel[SHADER_ENVIRONMENT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/decodeNormF.glsl", mVertexShaderLevel[SHADER_ENVIRONMENT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mVertexShaderLevel[SHADER_ENVIRONMENT] ) );
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] ) );
@@ -1003,6 +1058,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
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.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];
success = gWaterProgram.createShader(NULL, NULL);
}
@@ -1012,12 +1068,12 @@ 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 = mVertexShaderLevel[SHADER_WATER];
+ gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gUnderWaterProgram.createShader(NULL, NULL);
}
@@ -1162,6 +1218,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredUnderWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
+ gDeferredWLSunProgram.unload();
+ gDeferredWLMoonProgram.unload();
gDeferredStarProgram.unload();
gDeferredFullbrightShinyProgram.unload();
gDeferredSkinnedFullbrightShinyProgram.unload();
@@ -1181,6 +1239,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
+ gDeferredDiffuseProgram.mFeatures.encodesNormal = 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));
@@ -1192,6 +1251,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
@@ -1203,6 +1263,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
@@ -1213,6 +1274,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
@@ -1223,6 +1285,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader";
+ gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear();
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));
@@ -1235,6 +1298,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader";
gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = 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));
@@ -1246,6 +1310,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
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));
@@ -1261,6 +1326,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.decodesNormal = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = 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));
@@ -1279,6 +1352,7 @@ 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));
@@ -1323,6 +1397,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
bool has_skin = i & 0x10;
gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
+ gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
+ gDeferredMaterialProgram[i].mFeatures.decodesNormal = true;
+ gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
+ gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
+ gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
+
if (has_skin)
{
gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
@@ -1351,6 +1431,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
+ gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.decodesNormal = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.calculatesAtmospherics = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true;
+
if (has_skin)
{
gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
@@ -1383,6 +1470,7 @@ 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];
@@ -1402,6 +1490,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
+ gDeferredImpostorProgram.mFeatures.hasSrgb = true;
+ gDeferredImpostorProgram.mFeatures.decodesNormal = true;
+ gDeferredImpostorProgram.mFeatures.encodesNormal = 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));
@@ -1412,6 +1503,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredLightProgram.mName = "Deferred Light Shader";
+ gDeferredLightProgram.mFeatures.decodesNormal = 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));
@@ -1425,6 +1517,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+ gDeferredMultiLightProgram[i].mFeatures.decodesNormal = true;
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));
@@ -1438,6 +1531,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
gDeferredSpotLightProgram.mShaderFiles.clear();
+ gDeferredSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredSpotLightProgram.mFeatures.decodesNormal = true;
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];
@@ -1448,6 +1543,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
+ gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredMultiSpotLightProgram.mFeatures.decodesNormal = true;
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));
@@ -1475,6 +1572,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredSunProgram.mName = "Deferred Sun Shader";
+ gDeferredSunProgram.mFeatures.decodesNormal = true;
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));
@@ -1486,6 +1584,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
+ gDeferredBlurLightProgram.mFeatures.decodesNormal = 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));
@@ -1502,6 +1601,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mFeatures.hasLighting = false;
gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredAlphaProgram.mFeatures.decodesNormal = true;
+ gDeferredAlphaProgram.mFeatures.encodesNormal = true;
+ gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
+
if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
{
gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
@@ -1528,11 +1633,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader";
+ gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader";
gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false;
gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false;
gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true;
+ gDeferredAlphaImpostorProgram.mFeatures.decodesNormal = true;
+ gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true;
gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
{
@@ -1567,6 +1675,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaWaterProgram.mFeatures.hasLighting = false;
gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true;
+ gDeferredAlphaWaterProgram.mFeatures.decodesNormal = true;
+ gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true;
+ gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true;
+
if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
{
gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
@@ -1599,6 +1714,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
gDeferredAvatarEyesProgram.mFeatures.hasTransport = true;
gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarEyesProgram.mFeatures.encodesNormal = 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));
@@ -1612,6 +1729,7 @@ 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));
@@ -1626,6 +1744,7 @@ 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));
@@ -1641,6 +1760,8 @@ 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));
@@ -1657,6 +1778,8 @@ 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));
@@ -1690,6 +1813,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
@@ -1733,10 +1857,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredWaterProgram.mFeatures.hasGamma = true;
gDeferredWaterProgram.mFeatures.hasTransport = true;
+ gDeferredWaterProgram.mFeatures.encodesNormal = 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.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredWaterProgram.createShader(NULL, NULL);
}
@@ -1745,8 +1871,11 @@ 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.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));
@@ -1758,6 +1887,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSoftenProgram.mName = "Deferred Soften Shader";
gDeferredSoftenProgram.mShaderFiles.clear();
+ gDeferredSoftenProgram.mFeatures.hasSrgb = true;
+ gDeferredSoftenProgram.mFeatures.decodesNormal = true;
+ gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasTransport = true;
+ gDeferredSoftenProgram.mFeatures.hasGamma = true;
+
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));
@@ -1781,6 +1917,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true;
+ gDeferredSoftenWaterProgram.mFeatures.decodesNormal = true;
+ gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasTransport = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
@@ -1851,6 +1994,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gTerrainProgram.mName = "Deferred Terrain Shader";
+ gDeferredTerrainProgram.mFeatures.encodesNormal = 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));
@@ -1862,6 +2006,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
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));
@@ -1877,6 +2022,14 @@ 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.decodesNormal = true;
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasGamma = 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));
@@ -1894,6 +2047,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
+ gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = 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));
@@ -1955,23 +2109,71 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
//gWLSkyProgram.mFeatures.hasGamma = true;
- gDeferredWLSkyProgram.mShaderFiles.clear();
+ gDeferredWLSkyProgram.mShaderFiles.clear();
+ gDeferredWLSkyProgram.mFeatures.hasGamma = 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 = mVertexShaderLevel[SHADER_WINDLIGHT];
gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ if (gAtmosphere && mVertexShaderLevel[SHADER_WINDLIGHT] > 1)
+ {
+ gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink();
+ }
success = gDeferredWLSkyProgram.createShader(NULL, NULL);
+ llassert(success);
}
- if (success)
+ if (success)
{
gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
gDeferredWLCloudProgram.mShaderFiles.clear();
+ gDeferredWLCloudProgram.mFeatures.hasGamma = 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.mShaderGroup = LLGLSLShader::SG_SKY;
+ if (gAtmosphere && mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)
+ {
+ gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink();
+ }
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.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 = mVertexShaderLevel[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.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 = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gDeferredWLMoonProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -2236,6 +2438,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true;
gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true;
gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true;
+ gObjectFullbrightNonIndexedProgram.mFeatures.hasSrgb = true;
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));
@@ -2251,6 +2454,7 @@ 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));
@@ -2267,6 +2471,7 @@ 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));
@@ -2297,6 +2502,7 @@ 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));
@@ -2392,6 +2598,7 @@ 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));
@@ -2480,6 +2687,7 @@ 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));
@@ -2537,6 +2745,7 @@ 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));
@@ -2568,6 +2777,7 @@ 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));
@@ -2600,6 +2810,7 @@ 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));
@@ -2722,6 +2933,7 @@ 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));
@@ -2738,6 +2950,7 @@ 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));
@@ -3269,16 +3482,6 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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];
- success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
@@ -3297,21 +3500,35 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
}
BOOL LLViewerShaderMgr::loadShadersWindLight()
-{
+{
BOOL success = TRUE;
if (mVertexShaderLevel[SHADER_WINDLIGHT] < 2)
{
gWLSkyProgram.unload();
gWLCloudProgram.unload();
+ gWLSunProgram.unload();
+ gWLMoonProgram.unload();
+ gDownsampleMinMaxDepthRectProgram.unload();
+ gInscatterRectProgram.unload();
return TRUE;
}
+#if USE_ADVANCED_ATMOSPHERICS
+// disabled until we can determine why low-end machines crash during this init...
+ if (mVertexShaderLevel[SHADER_WINDLIGHT] > 1)
+ {
+ // Prepare precomputed atmospherics textures using libatmosphere
+ LLAtmosphere::initClass();
+ }
+#endif
+
if (success)
{
gWLSkyProgram.mName = "Windlight Sky Shader";
//gWLSkyProgram.mFeatures.hasGamma = true;
gWLSkyProgram.mShaderFiles.clear();
+ gWLSkyProgram.mFeatures.hasGamma = 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 = mVertexShaderLevel[SHADER_WINDLIGHT];
@@ -3324,6 +3541,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLCloudProgram.mName = "Windlight Cloud Program";
//gWLCloudProgram.mFeatures.hasGamma = true;
gWLCloudProgram.mShaderFiles.clear();
+ gWLCloudProgram.mFeatures.hasGamma = 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 = mVertexShaderLevel[SHADER_WINDLIGHT];
@@ -3331,6 +3549,42 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
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 = mVertexShaderLevel[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 = mVertexShaderLevel[SHADER_WINDLIGHT];
+ gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gWLMoonProgram.createShader(NULL, NULL);
+ }
+
return success;
}
@@ -3430,8 +3684,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 923aa522ad..250f8f1ee3 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -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;
@@ -184,6 +166,8 @@ extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;
extern LLGLSLShader gDownsampleDepthProgram;
extern LLGLSLShader gDownsampleDepthRectProgram;
+extern LLGLSLShader gDownsampleMinMaxDepthRectProgram;
+extern LLGLSLShader gInscatterRectProgram;
extern LLGLSLShader gBenchmarkProgram;
//output tex0[tc0] + tex1[tc1]
@@ -277,6 +261,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;
@@ -331,6 +317,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/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 7d2d6e25c7..6899424cf6 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 2e366835d9..82932ef6ae 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::sFreezeImageScalingDown = FALSE;
F32 LLViewerTexture::sCurrentTime = 0.0f;
F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
@@ -1193,12 +1193,12 @@ void LLViewerFetchedTexture::loadFromFastCache()
{
return; //no need to access the fast cache.
}
- mInFastCacheList = FALSE;
+ mInFastCacheList = FALSE;
mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel);
if(mRawImage.notNull())
{
- mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
+ mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
setTexelsPerImage();
@@ -1213,20 +1213,20 @@ void LLViewerFetchedTexture::loadFromFastCache()
else
{
if (mBoostLevel == LLGLTexture::BOOST_ICON)
+ {
+ 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))
{
- 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))
- {
- // scale oversized icon, no need to give more work to gl
- mRawImage->scale(expected_width, expected_height);
- }
+ // scale oversized icon, no need to give more work to gl
+ mRawImage->scale(expected_width, expected_height);
+ }
}
- mRequestedDiscardLevel = mDesiredDiscardLevel + 1;
- mIsRawImageValid = TRUE;
- addToCreateTexture();
- }
+ mRequestedDiscardLevel = mDesiredDiscardLevel + 1;
+ mIsRawImageValid = TRUE;
+ addToCreateTexture();
+ }
}
}
@@ -1993,7 +1993,7 @@ bool LLViewerFetchedTexture::updateFetch()
mIsFetched = TRUE;
tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID));
}
- mRawDiscardLevel = fetch_discard;
+ mRawDiscardLevel = fetch_discard;
if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
(current_discard < 0 || mRawDiscardLevel < current_discard))
{
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 5d89f9f029..7b58c97bc4 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -225,8 +225,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 sFreezeImageScalingDown ;//do not scale down image res if set.
static F32 sCurrentTime ;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 01ec703fe6..58f26d6a2b 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -594,7 +594,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()));
@@ -1702,7 +1702,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
U32 fsaa_samples)
*/
// create window
- mWindow = LLWindowManager::createWindow(this,
+ mWindow = LLWindowManager::createWindow(this,
p.title, p.name, p.x, p.y, p.width, p.height, 0,
p.fullscreen,
gHeadlessClient,
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/llvosky.cpp b/indra/newview/llvosky.cpp
index c131cb886f..c6267d50ff 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -48,152 +48,42 @@
#include "llworld.h"
#include "pipeline.h"
#include "lldrawpoolwlsky.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
+#include "v3colorutil.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;
+#include "llsettingssky.h"
+#include "llenvironment.h"
-// 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;
+#include "lltrace.h"
+#include "llfasttimer.h"
-// 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);
-
-// Exported globals
-LLUUID gSunTextureID = IMG_SUN;
-LLUUID gMoonTextureID = IMG_MOON;
+#undef min
+#undef max
-class LLFastLn
+namespace
{
-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.
+ const S32 NUM_TILES_X = 8;
+ const S32 NUM_TILES_Y = 4;
+ const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
-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);
-}
+ // Heavenly body constants
+ const F32 SUN_DISK_RADIUS = 0.5f;
+ const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
+ const F32 SUN_INTENSITY = 1e5;
-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);
-}
+ // Texture coordinates:
+ 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);
-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;
-}
+ const F32 LIGHT_DIRECTION_THRESHOLD = (F32) cosf(DEG_TO_RAD * 1.f);
+ const F32 COLOR_CHANGE_THRESHOLD = 0.01f;
-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);
- }
-}
+ LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATETIMER("VOSky Update Timer Tick");
+ LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATEFORCED("VOSky Update Forced");
-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 );
+ F32Seconds UPDATE_EXPRY(2.0f);
}
-
-// 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
***************************************/
@@ -249,6 +139,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)
{
@@ -289,9 +205,6 @@ void LLSkyTex::create(const F32 brightness)
createGLImage(sCurrent);
}
-
-
-
void LLSkyTex::createGLImage(S32 which)
{
mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
@@ -300,15 +213,176 @@ void LLSkyTex::createGLImage(S32 which)
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 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;
@@ -326,32 +400,15 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
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();
+ mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY);
+ mForceUpdateThrottle.reset();
+
for (S32 i = 0; i < 6; i++)
{
mSkyTex[i].init();
@@ -366,32 +423,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,11 +443,33 @@ 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();
+
+ 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.max_y = psky->getMaxY();
+ vars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+ 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();
// Initialize the cached normalized direction vectors
for (S32 side = 0; side < 6; ++side)
@@ -418,7 +477,7 @@ void LLVOSky::init()
for (S32 tile = 0; tile < NUM_TILES; ++tile)
{
initSkyTextureDirs(side, tile);
- createSkyTexture(side, tile);
+ createSkyTexture(vars, side, tile);
}
}
@@ -429,6 +488,7 @@ void LLVOSky::init()
}
initCubeMap();
+
mInitialized = true;
mHeavenlyBodyUpdated = FALSE ;
@@ -474,15 +534,16 @@ void LLVOSky::restoreGL()
{
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();
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ if (psky)
+ {
+ setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId());
+ setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId());
+ }
+
+ updateDirections();
if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap
&& LLCubeMap::sUseCubeMaps)
@@ -498,10 +559,11 @@ void LLVOSky::restoreGL()
if(cube_map)
{
cube_map->init(images);
- mForceUpdate = TRUE;
}
}
+ mForceUpdate = TRUE;
+
if (mDrawable)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
@@ -541,7 +603,7 @@ 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)
{
S32 tile_x = tile % NUM_TILES_X;
S32 tile_y = tile / NUM_TILES_X;
@@ -554,491 +616,35 @@ 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);
- }
- }
-}
-
-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)
-{
- return LLColor3(exp(v.mV[0]),
- exp(v.mV[1]),
- exp(v.mV[2]));
-}
-
-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));
-}
-
-static inline LLColor3 componentSaturate(LLColor3 const &v)
-{
- 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)
-{
- return LLColor3(sqrt(v.mV[0]),
- sqrt(v.mV[1]),
- sqrt(v.mV[2]));
-}
-
-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];
-}
-
-static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
-{
- return (left + ((right - left) * amount));
-}
-
-static inline LLColor3 smear(F32 val)
-{
- return LLColor3(val, val, val);
-}
-
-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)
- {
- lightnorm.mV[1] = -0.1f;
- }
-
-}
-
-LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny)
-{
- F32 saturation = 0.3f;
- if (dir.mV[VZ] < -0.02f)
- {
- 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;
- }
-
- // 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)
- {
- 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;
- }
-
- F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA;
-
- Pn *= Plen;
-
- vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]);
- vary_HorizontalProjection[0] /= - 2.f * 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 = 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]));
-
- // 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
- 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)
- {
- vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f));
+ mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, mSkyTex[side].getDir(x, y)), x, y);
+ mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, mSkyTex[side].getDir(x, y), true), x, y);
}
}
}
-#if LL_MSVC && __MSVC_VER__ < 8
-#pragma optimize("p", off)
-#endif
-
-LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
- LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
- LLVector2 vary_HorizontalProjection[2])
+void LLVOSky::updateDirections(void)
{
- LLColor3 res;
-
- LLColor3 color0 = vary_HazeColor;
-
- if (!gPipeline.canUseWindLightShaders())
- {
- LLColor3 color1 = color0 * 2.0f;
- color1 = smear(1.f) - componentSaturate(color1);
- componentPow(color1, gamma);
- res = smear(1.f) - color1;
- }
- else
- {
- res = color0;
- }
-
-# ifndef LL_RELEASE_FOR_DOWNLOAD
-
- LLColor3 color2 = 2.f * color0;
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- 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)
- {
- 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;
-}
-
-LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
-{
- return componentMult(diffuse, sundiffuse) * 4.0f +
- componentMult(ambient, sundiffuse) * 2.0f + sunambient;
-}
-
-LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
-{
- return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f;
-}
-
-
-void LLVOSky::calcAtmospherics(void)
-{
- initAtmospherics();
-
- LLColor3 vary_HazeColor;
- LLColor3 vary_SunlightColor;
- LLColor3 vary_AmbientColor;
- {
- // 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;
- }
-
- temp2.mV[1] = llmax(0.f, lighty);
- if(temp2.mV[1] > 0.f)
- {
- temp2.mV[1] = 1.f / temp2.mV[1];
- }
- 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);
+ mSun.setColor(psky->getSunlightColor());
mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
mSun.renewDirection();
mSun.renewColor();
mMoon.renewDirection();
mMoon.renewColor();
-
- float dp = getToSunLast() * LLVector3(0,0,1.f);
- if (dp < 0)
- {
- dp = 0;
- }
-
- // 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);
-
- mSunDiffuse = vary_SunlightColor;
- mSunAmbient = vary_AmbientColor;
- mMoonDiffuse = vary_SunlightColor;
- mMoonAmbient = vary_AmbientColor;
-
- mTotalAmbient = vary_AmbientColor;
- mTotalAmbient.setAlpha(1);
-
- mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
- mFadeColor.setAlpha(0);
}
void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
{
}
-BOOL LLVOSky::updateSky()
-{
+bool LLVOSky::updateSky()
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLColor4 total_ambient = psky->getTotalAmbient();
+
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
{
return TRUE;
@@ -1058,11 +664,13 @@ BOOL LLVOSky::updateSky()
const S32 total_no_tiles = 6 * NUM_TILES;
const S32 cycle_frame_no = total_no_tiles + 1;
- if (mUpdateTimer.getElapsedTimeF32() > 0.001f)
+ if (mUpdateTimer.getElapsedTimeF32() > 0.025f)
{
- mUpdateTimer.reset();
+ mUpdateTimer.reset();
const S32 frame = next_frame;
+ mForceUpdate = mForceUpdate || (total_no_tiles == frame);
+
++next_frame;
next_frame = next_frame % cycle_frame_no;
@@ -1070,117 +678,156 @@ BOOL LLVOSky::updateSky()
// sInterpVal = (F32)next_frame / cycle_frame_no;
LLSkyTex::setInterpVal( mInterpVal );
LLHeavenBody::setInterpVal( mInterpVal );
- calcAtmospherics();
+ updateDirections();
+
+ LLVector3 direction = mSun.getDirection();
+ direction.normalize();
+ const F32 dot_lighting = direction * mLastLightingDirection;
- if (mForceUpdate || total_no_tiles == frame)
+ //_WARNS("LAPRAS") << " <" << direction.getValue() << "> dot <" << mLastLightingDirection << "> = " << dot_lighting << " (threshold is " << LIGHT_DIRECTION_THRESHOLD << ")" << LL_ENDL;
+
+ LLColor3 delta_color;
+ delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0],
+ mLastTotalAmbient.mV[1] - total_ambient.mV[1],
+ mLastTotalAmbient.mV[2] - total_ambient.mV[2]);
+
+ bool light_direction_changed = (dot_lighting < LIGHT_DIRECTION_THRESHOLD);
+ bool color_changed = (delta_color.length() >= COLOR_CHANGE_THRESHOLD);
+
+ mForceUpdate = mForceUpdate || light_direction_changed;
+ mForceUpdate = mForceUpdate || color_changed;
+ mForceUpdate = mForceUpdate || !mInitialized;
+
+ if (mForceUpdate && mForceUpdateThrottle.hasExpired())
{
+ LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED);
+
+ mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY);
+
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 (!direction.isExactlyZero())
{
mLastLightingDirection = direction;
- mLastTotalAmbient = mTotalAmbient;
+ mLastTotalAmbient = total_ambient;
mInitialized = TRUE;
if (mCubeMap)
{
- if (mForceUpdate)
+ updateFog(LLViewerCamera::getInstance()->getFar());
+
+ 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.max_y = psky->getMaxY();
+ vars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+ 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();
+
+ for (int side = 0; side < 6; side++)
{
- updateFog(LLViewerCamera::getInstance()->getFar());
- for (int side = 0; side < 6; side++)
- {
- for (int tile = 0; tile < NUM_TILES; tile++)
- {
- createSkyTexture(side, tile);
- }
- }
-
- calcAtmospherics();
-
- for (int side = 0; side < 6; side++)
+ for (int tile = 0; tile < NUM_TILES; tile++)
{
- 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));
+ createSkyTexture(vars, side, tile);
}
- next_frame = 0;
}
- }
- }
- /// *TODO really, sky texture and env map should be shared on a single texture
- /// I'll let Brad take this at some point
+ int tex = mSkyTex[0].getWhich(TRUE);
- // update the sky texture
- for (S32 i = 0; i < 6; ++i)
- {
- mSkyTex[i].create(1.0f);
- mShinyTex[i].create(1.0f);
- }
-
- // 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));
+ for (int side = 0; side < 6; side++)
+ {
+ LLImageRaw* raw1 = nullptr;
+ LLImageRaw* raw2 = nullptr;
+ 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
+ for (S32 i = 0; i < 6; ++i)
+ {
+ mSkyTex[i].create(1.0f);
+ mShinyTex[i].create(1.0f);
+ }
+
+ // 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();
+ }
}
- mCubeMap->init(images);
- gGL.getTexUnit(0)->disable();
- }
+ }
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);
-
mForceUpdate = FALSE;
}
- else
- {
- const S32 side = frame / NUM_TILES;
- const S32 tile = frame % NUM_TILES;
- createSkyTexture(side, tile);
- }
}
if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
}
+
return TRUE;
}
void LLVOSky::updateTextures()
{
- if (mSunTexturep)
+ if (mSunTexturep[0])
+ {
+ mSunTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
+ }
+
+ if (mSunTexturep[1])
+ {
+ mSunTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
+ }
+
+ if (mMoonTexturep[0])
{
- mSunTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
- mMoonTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
- mBloomTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
+ mMoonTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
+ }
+
+ if (mMoonTexturep[1])
+ {
+ mMoonTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
+ }
+
+ if (mBloomTexturep[0])
+ {
+ mBloomTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
+ }
+
+ if (mBloomTexturep[1])
+ {
+ mBloomTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
}
@@ -1198,60 +845,113 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)
mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
}
- mFace[FACE_SUN] = mDrawable->addFace(poolp, mSunTexturep);
- mFace[FACE_MOON] = mDrawable->addFace(poolp, mMoonTexturep);
- mFace[FACE_BLOOM] = mDrawable->addFace(poolp, mBloomTexturep);
+ mFace[FACE_SUN] = mDrawable->addFace(poolp, nullptr);
+ mFace[FACE_MOON] = mDrawable->addFace(poolp, nullptr);
+ mFace[FACE_BLOOM] = mDrawable->addFace(poolp, nullptr);
return mDrawable;
}
-//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::setSunScale(F32 sun_scale)
{
- if(!mFace[FACE_DUMMY])
- {
- LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
- mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL);
- }
+ mSunScale = sun_scale;
+}
- 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);
- }
+void LLVOSky::setMoonScale(F32 moon_scale)
+{
+ mMoonScale = moon_scale;
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update");
+void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
+{
+ // 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);
+
+ if (mFace[FACE_SUN])
+ {
+ if (mSunTexturep[0])
+ {
+ mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
+
+ if (mSunTexturep[1])
+ {
+ mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]);
+ }
+}
-void LLVOSky::updateDummyVertexBuffer()
-{
- if(!LLVertexBuffer::sEnableVBOs)
- return ;
+void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next)
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLUUID moon_tex = moon_texture.isNull() ? psky->GetDefaultMoonTextureId() : moon_texture;
+ LLUUID moon_tex_next = moon_texture_next.isNull() ? (moon_texture.isNull() ? psky->GetDefaultMoonTextureId() : moon_texture) : moon_texture_next;
+
+ mMoonTexturep[0] = moon_tex.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mMoonTexturep[1] = moon_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+
+ if (mFace[FACE_MOON])
+ {
+ if (mMoonTexturep[0])
+ {
+ mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
+
+ if (mMoonTexturep[1])
+ {
+ mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
+ }
+ }
+}
- if(mHeavenlyBodyUpdated)
- {
- mHeavenlyBodyUpdated = FALSE ;
- return ;
- }
+void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLUUID cloud_noise_tex = cloud_noise_texture.isNull() ? psky->GetDefaultCloudNoiseTextureId() : cloud_noise_texture;
+ LLUUID cloud_noise_tex_next = cloud_noise_texture_next.isNull() ? (cloud_noise_texture.isNull() ? psky->GetDefaultCloudNoiseTextureId() : cloud_noise_texture) : cloud_noise_texture_next;
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FAKE_VBO_UPDATE) ;
+ mCloudNoiseTexturep[0] = LLViewerTextureManager::getFetchedTexture(cloud_noise_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mCloudNoiseTexturep[1] = LLViewerTextureManager::getFetchedTexture(cloud_noise_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer())
- createDummyVertexBuffer() ;
+ if (mCloudNoiseTexturep[0])
+ {
+ mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
+ }
- LLStrider<LLVector3> vertices ;
- mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices, 0);
- *vertices = mCameraPosAgent ;
- mFace[FACE_DUMMY]->getVertexBuffer()->flush();
+ if (mCloudNoiseTexturep[1])
+ {
+ mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP);
+ }
}
-//----------------------------------
-//end of fake vertex buffer updating
-//----------------------------------
+
+void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next)
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ 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;
+
+ 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);
+
+ if (mBloomTexturep[0])
+ {
+ mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ if (mBloomTexturep[1])
+ {
+ mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+}
+
static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");
BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
@@ -1267,6 +967,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
}
mCameraPosAgent = drawable->getPositionAgent();
+
mEarthCenter.mV[0] = mCameraPosAgent.mV[0];
mEarthCenter.mV[1] = mCameraPosAgent.mV[1];
@@ -1340,64 +1041,40 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
LLVector3 up = right % look_at;
right.normalize();
up.normalize();
+
+ 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();
- 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));
+ 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;
- }
- else
- {
- sun_flag = TRUE;
- }
+ {
+ sun_flag = !mMoon.isVisible() || ((look_at * mSun.getDirection()) > 0);
}
- if (height_above_water > 0)
- {
- BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
-
- if (sun_flag)
- {
- setDrawRefl(0);
- if (render_ref)
- {
- updateReflectionGeometry(drawable, height_above_water, mSun);
- }
- }
- else
- {
- setDrawRefl(1);
- if (render_ref)
- {
- updateReflectionGeometry(drawable, height_above_water, mMoon);
- }
- }
- }
- else
- {
- setDrawRefl(-1);
- }
+ bool above_water = (height_above_water > 0);
+ bool render_ref = above_water && gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
+ setDrawRefl(above_water ? (sun_flag ? 0 : 1) : -1);
+ if (render_ref)
+ {
+ updateReflectionGeometry(drawable, height_above_water, mSun);
+ }
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 +1085,28 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
S32 index_offset;
LLFace *facep;
- LLVector3 to_dir = hb.getDirection();
-
- if (!is_sun)
- {
- to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f);
- }
+ LLVector3 to_dir = hb.getDirection();
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] );
+ 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 +1156,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 +1220,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 +1234,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 +1249,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 +1337,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,408 +1349,229 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
LLFace *face = mFace[FACE_REFLECTION];
- if (!face->getVertexBuffer() || quads*4 != face->getGeomCount())
- {
- face->setSize(quads * 4, quads * 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
- if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
- {
- LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
- << face->getGeomCount() << " vertices and "
- << face->getIndicesCount() << " indices" << LL_ENDL;
- }
- face->setIndicesIndex(0);
- face->setGeomIndex(0);
- face->setVertexBuffer(buff);
- }
-
- LLStrider<LLVector3> verticesp;
- LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texCoordsp;
- LLStrider<U16> indicesp;
- S32 index_offset;
-
- index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
- if (-1 == index_offset)
- {
- return;
- }
-
- LLColor3 hb_col3 = HB.getInterpColor();
- hb_col3.clamp();
- const LLColor4 hb_col = LLColor4(hb_col3);
-
- const F32 min_attenuation = 0.4f;
- const F32 max_attenuation = 0.7f;
- const F32 attenuation = min_attenuation
- + cos_angle_of_view * (max_attenuation - min_attenuation);
-
- LLColor4 hb_refl_col = (1-attenuation) * hb_col + attenuation * mFogColor;
- face->setFaceColor(hb_refl_col);
-
- LLVector3 v_far[2];
- v_far[0] = v_refl_corner[1];
- v_far[1] = v_refl_corner[3];
-
- if(dt_clip > 0)
- {
- if (dt_clip >= 1)
- {
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- F32 ratio = far_clip / v_refl_corner[vtx].length();
- *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent;
- }
- const LLVector3 draw_pos = 0.25 *
- (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]);
- face->mCenterAgent = draw_pos;
- }
- else
- {
- F32 ratio = far_clip / v_refl_corner[1].length();
- v_sprite_corner[1] = v_refl_corner[1] * ratio;
-
- ratio = far_clip / v_refl_corner[3].length();
- v_sprite_corner[3] = v_refl_corner[3] * ratio;
-
- v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0];
- v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2];
- v_sprite_corner[0] = v_refl_corner[1];
- v_sprite_corner[2] = v_refl_corner[3];
-
- for (S32 vtx = 0; vtx < 4; ++vtx)
+ if (face)
+ {
+ if (!face->getVertexBuffer() || quads * 4 != face->getGeomCount())
+ {
+ face->setSize(quads * 4, quads * 6);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
- *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent;
+ LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
+ << face->getGeomCount() << " vertices and "
+ << face->getIndicesCount() << " indices" << LL_ENDL;
}
-
- const LLVector3 draw_pos = 0.25 *
- (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]);
- face->mCenterAgent = draw_pos;
- }
-
- *(texCoordsp++) = TEX0tt;
- *(texCoordsp++) = TEX0t;
- *(texCoordsp++) = TEX1tt;
- *(texCoordsp++) = TEX1t;
-
- *indicesp++ = index_offset + 0;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 1;
-
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
-
- index_offset += 4;
- }
-
- if (dt_clip < 1)
- {
- if (dt_clip <= 0)
- {
- const LLVector3 draw_pos = 0.25 *
- (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]);
- face->mCenterAgent = draw_pos;
- }
-
- const F32 raws_inv = 1.f/raws;
- const F32 cols_inv = 1.f/cols;
- LLVector3 left = v_refl_corner[0] - v_refl_corner[1];
- LLVector3 right = v_refl_corner[2] - v_refl_corner[3];
- left *= raws_inv;
- right *= raws_inv;
-
- F32 dt_raw = dt;
-
- for (S32 raw = 0; raw < raws; ++raw)
- {
- F32 dt_v0 = raw * raws_inv;
- F32 dt_v1 = (raw + 1) * raws_inv;
- const LLVector3 BL = v_refl_corner[1] + (F32)raw * left;
- 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);
- for (S32 col = 0; col < cols; ++col)
- {
- F32 dt_h0 = col * cols_inv;
- *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent;
- *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent;
- F32 dt_h1 = (col + 1) * cols_inv;
- *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent;
- *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent;
-
- *(texCoordsp++) = LLVector2(dt_h0, dt_v1);
- *(texCoordsp++) = LLVector2(dt_h0, dt_v0);
- *(texCoordsp++) = LLVector2(dt_h1, dt_v1);
- *(texCoordsp++) = LLVector2(dt_h1, dt_v0);
-
- *indicesp++ = index_offset + 0;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 1;
-
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
-
- index_offset += 4;
- }
- }
- }
-
- face->getVertexBuffer()->flush();
+ face->setIndicesIndex(0);
+ face->setGeomIndex(0);
+ face->setVertexBuffer(buff);
+ }
+
+ LLStrider<LLVector3> verticesp;
+ LLStrider<LLVector3> normalsp;
+ LLStrider<LLVector2> texCoordsp;
+ LLStrider<U16> indicesp;
+ S32 index_offset;
+
+ index_offset = face->getGeometry(verticesp, normalsp, texCoordsp, indicesp);
+ if (-1 == index_offset)
+ {
+ return;
+ }
+
+ LLColor3 hb_col3 = HB.getInterpColor();
+ hb_col3.clamp();
+ const LLColor4 hb_col = LLColor4(hb_col3);
+
+ const F32 min_attenuation = 0.4f;
+ const F32 max_attenuation = 0.7f;
+ const F32 attenuation = min_attenuation
+ + cos_angle_of_view * (max_attenuation - min_attenuation);
+
+ LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor();
+ face->setFaceColor(hb_refl_col);
+
+ LLVector3 v_far[2];
+ v_far[0] = v_refl_corner[1];
+ v_far[1] = v_refl_corner[3];
+
+ if (dt_clip > 0)
+ {
+ if (dt_clip >= 1)
+ {
+ for (S32 vtx = 0; vtx < 4; ++vtx)
+ {
+ F32 ratio = far_clip / v_refl_corner[vtx].length();
+ *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent;
+ }
+ const LLVector3 draw_pos = 0.25 *
+ (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]);
+ face->mCenterAgent = draw_pos;
+ }
+ else
+ {
+ F32 ratio = far_clip / v_refl_corner[1].length();
+ v_sprite_corner[1] = v_refl_corner[1] * ratio;
+
+ ratio = far_clip / v_refl_corner[3].length();
+ v_sprite_corner[3] = v_refl_corner[3] * ratio;
+
+ v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0];
+ v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2];
+ v_sprite_corner[0] = v_refl_corner[1];
+ v_sprite_corner[2] = v_refl_corner[3];
+
+ for (S32 vtx = 0; vtx < 4; ++vtx)
+ {
+ *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent;
+ }
+
+ const LLVector3 draw_pos = 0.25 *
+ (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]);
+ face->mCenterAgent = draw_pos;
+ }
+
+ *(texCoordsp++) = TEX0tt;
+ *(texCoordsp++) = TEX0t;
+ *(texCoordsp++) = TEX1tt;
+ *(texCoordsp++) = TEX1t;
+
+ *indicesp++ = index_offset + 0;
+ *indicesp++ = index_offset + 2;
+ *indicesp++ = index_offset + 1;
+
+ *indicesp++ = index_offset + 1;
+ *indicesp++ = index_offset + 2;
+ *indicesp++ = index_offset + 3;
+
+ index_offset += 4;
+ }
+
+ if (dt_clip < 1)
+ {
+ if (dt_clip <= 0)
+ {
+ const LLVector3 draw_pos = 0.25 *
+ (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]);
+ face->mCenterAgent = draw_pos;
+ }
+
+ const F32 raws_inv = 1.f / raws;
+ const F32 cols_inv = 1.f / cols;
+ LLVector3 left = v_refl_corner[0] - v_refl_corner[1];
+ LLVector3 right = v_refl_corner[2] - v_refl_corner[3];
+ left *= raws_inv;
+ right *= raws_inv;
+
+ for (S32 raw = 0; raw < raws; ++raw)
+ {
+ F32 dt_v0 = raw * raws_inv;
+ F32 dt_v1 = (raw + 1) * raws_inv;
+ const LLVector3 BL = v_refl_corner[1] + (F32)raw * left;
+ const LLVector3 BR = v_refl_corner[3] + (F32)raw * right;
+ const LLVector3 EL = BL + left;
+ const LLVector3 ER = BR + right;
+ 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;
+ *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent;
+ *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent;
+ F32 dt_h1 = (col + 1) * cols_inv;
+ *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent;
+ *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent;
+
+ *(texCoordsp++) = LLVector2(dt_h0, dt_v1);
+ *(texCoordsp++) = LLVector2(dt_h0, dt_v0);
+ *(texCoordsp++) = LLVector2(dt_h1, dt_v1);
+ *(texCoordsp++) = LLVector2(dt_h1, dt_v0);
+
+ *indicesp++ = index_offset + 0;
+ *indicesp++ = index_offset + 2;
+ *indicesp++ = index_offset + 1;
+
+ *indicesp++ = index_offset + 1;
+ *indicesp++ = index_offset + 2;
+ *indicesp++ = index_offset + 3;
+
+ index_offset += 4;
+ }
+ }
+ }
+
+ face->getVertexBuffer()->flush();
+ }
}
-
-
-
void LLVOSky::updateFog(const F32 distance)
{
- 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;
-
- 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++)
- {
- 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;
+ LLEnvironment& environment = LLEnvironment::instance();
+ if (environment.getCurrentSky() != nullptr)
+ {
+ LLVector3 light_dir = LLVector3(environment.getClampedLightNorm());
+ m_legacyAtmospherics.updateFog(distance, light_dir);
+ }
+}
- 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;
-
- // 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"));
+void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr)
+{
+ mSun.setDirection(sun_dir_cfr);
+ mMoon.setDirection(moon_dir_cfr);
- LLColor4 fogCol = water_fog_color * depth_modifier;
- fogCol.setAlpha(1);
+ mLastLightingDirection = mSun.getDirection();
- // set the gl fog color
- mGLFogCol = fogCol;
+ // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+ // on the upward facing faces of cubes.
+ {
+ // Same as dot product with the up direction + clamp.
+ F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+ sunDot *= sunDot;
- // set the density based on what the shaders use
- fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
+ // 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;
- 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();
+ }
- mFogColor = sky_fog_color;
- mFogColor.setAlpha(1);
- LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f;
+ updateDirections();
- 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();
+ mForceUpdate = true;
}
-
-// Functions used a lot.
-F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)
+void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr)
{
- F32 mv = color_max(col);
- if (0 == mv)
- {
- return 0;
- }
+ mSun.setDirection(sun_dir_cfr);
- col *= 1.f / mv;
- color_pow(col, e);
- if (postmultiply)
- {
- col *= mv;
- }
- return mv;
-}
+ mLastLightingDirection = mSun.getDirection();
-// 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;
-}
+ // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+ // on the upward facing faces of cubes.
+ {
+ // Same as dot product with the up direction + clamp.
+ F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+ sunDot *= sunDot;
-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();
+ // 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;
- calcAtmospherics();
+ // 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();
+ }
- if ( !mInitialized )
- {
- init();
- LLSkyTex::stepCurrent();
- }
+ updateDirections();
+
+ mForceUpdate = true;
}
-void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
+void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr)
{
- LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir;
- sun_direction.normalize();
+ mMoon.setDirection(moon_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]);
- 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;
-
- // 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.normalize();
-
- 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;
- }
+ updateDirections();
+
+ mForceUpdate = true;
}
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 9cfb9773bd..ed190892fe 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -33,83 +33,18 @@
#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 - 10.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;
@@ -139,11 +74,11 @@ protected:
~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);
@@ -183,7 +118,7 @@ protected:
return col;
}
- LLImageRaw* getImageRaw(BOOL curr=TRUE) { return mImageRaw[getWhich(curr)]; }
+ LLImageRaw* getImageRaw(BOOL curr=TRUE);
void createGLImage(BOOL curr=TRUE);
};
@@ -200,241 +135,63 @@ protected:
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; }
+ const LLVector3& getDirection() const;
+ void setDirection(const LLVector3 &direction);
+ void setAngularVelocity(const LLVector3 &ang_vel);
+ const LLVector3& getAngularVelocity() const;
- void setDraw(const BOOL draw) { mDraw = draw; }
- BOOL getDraw() const { return mDraw; }
-
- 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; }
-};
-
-
-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; }
-
- 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;
- }
+ const LLVector3& getDirectionCached() const;
+ void renewDirection();
- void setFalloff(const F32 fo)
- {
- mFalloff = fo;
- }
+ const LLColor3& getColorCached() const;
+ void setColorCached(const LLColor3& c);
+ const LLColor3& getColor() const;
+ void setColor(const LLColor3& c);
- F32 getAbsCoef() const
- {
- return mAbsCoef;
- }
+ void renewColor();
- inline static F32 calcFalloff(const F32 h)
- {
- return (h <= 0) ? 1.0f : (F32)LL_FAST_EXP(-ATM_EXP_FALLOFF * h);
- }
+ static F32 interpVal();
+ static void setInterpVal(const F32 v);
- inline LLColor3 calcSigSca(const F32 h) const
- {
- return calcFalloff(h * mFalloff) * mSigSca;
- }
+ LLColor3 getInterpColor() const;
- inline void calcSigSca(const F32 h, LLColor3 &result) const
- {
- result = mSigSca;
- result *= calcFalloff(h * mFalloff);
- }
+ const F32& getVisibility() const;
+ void setVisibility(const F32 c = 1);
- LLColor3 calcSigExt(const F32 h) const
- {
- return calcFalloff(h * mFalloff) * (1 + mAbsCoef) * mSigSca;
- }
+ bool isVisible() const;
+ void setVisible(const bool v);
- F32 calcPhase(const F32 cos_theta) const;
+ const F32& getIntensity() const;
+ void setIntensity(const F32 c);
- static inline LLColor3 calcAirSca(const F32 h);
- static inline void calcAirSca(const F32 h, LLColor3 &result);
+ void setDiskRadius(const F32 radius);
+ F32 getDiskRadius() const;
-private:
- static LLColor3 const sAirScaSeaLevel;
- static F32 const sAirScaIntense;
- static F32 const sAirScaAvg;
+ void setDraw(const bool draw);
+ bool getDraw() const;
-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 +204,6 @@ public:
FACE_MOON, // was 7
FACE_BLOOM, // was 8
FACE_REFLECTION, // was 10
- FACE_DUMMY, //for an ATI bug --bao
FACE_COUNT
};
@@ -462,7 +218,7 @@ public:
void restoreGL();
/*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 +226,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);
-
- 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);
- }
+ // 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);
- 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,12 +260,27 @@ 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; }
+ 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* 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) { mForceUpdate = TRUE; }
public:
@@ -553,9 +290,18 @@ public:
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];
+
+ F32 mSunScale = 1.0f;
+ F32 mMoonScale = 1.0f;
static S32 sResolution;
static S32 sTileResX;
@@ -575,73 +321,27 @@ 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
+ bool mInitialized;
+ bool mForceUpdate; //flag to force instantaneous update of cubemap
LLVector3 mLastLightingDirection;
LLColor3 mLastTotalAmbient;
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 ;
+ 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/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7d6881f8a8..f046a903ed 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2152,7 +2152,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
switch(range_it->second.map)
{
- case LLRender::DIFFUSE_MAP:
+ case LLRender::DIFFUSE_MAP:
{
if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 3b9b96e9f1..933bf9bf12 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -32,11 +32,11 @@
#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 F32 LLVOWLSky::DISTANCE_TO_STARS = (HORIZON_DIST - 10.f) * 0.8f;
const U32 LLVOWLSky::MIN_SKY_DETAIL = 3;
const U32 LLVOWLSky::MAX_SKY_DETAIL = 180;
@@ -87,11 +87,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)
{
@@ -130,167 +125,22 @@ 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;
+ mFanVerts = nullptr;
mStripsVerts.clear();
- mStarsVerts = NULL;
+ mStarsVerts = nullptr;
+ mFsSkyVerts = nullptr;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
void LLVOWLSky::cleanupGL()
{
- mFanVerts = NULL;
+ mFanVerts = nullptr;
mStripsVerts.clear();
- mStarsVerts = NULL;
+ mStarsVerts = nullptr;
+ mFsSkyVerts = nullptr;
LLDrawPoolWLSky::cleanupGL();
}
@@ -305,12 +155,50 @@ 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
+ 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 full screen sky update" << LL_ENDL;
+ }
+
+ BOOL success = mFsSkyVerts->getVertexStrider(vertices)
+ && mFsSkyVerts->getTexCoord0Strider(texCoords)
+ && mFsSkyVerts->getIndexStrider(indices);
+
+ if(!success)
+ {
+ LL_ERRS() << "Failed updating WindLight fullscreen sky geometry." << LL_ENDL;
+ }
+
+ *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);
+
+ *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();
+ }
+
+ if(mFanVerts.isNull())
{
mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
if (!mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE))
@@ -406,85 +294,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);
@@ -504,6 +313,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())
@@ -515,7 +339,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)
@@ -531,16 +354,6 @@ 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();
}
@@ -584,7 +397,7 @@ void LLVOWLSky::buildFanBuffer(LLStrider<LLVector3> & vertices,
LLStrider<LLVector2> & texCoords,
LLStrider<U16> & indices)
{
- const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius();
+ const F32 RADIUS = LLEnvironment::instance().getCurrentSky()->getDomeRadius();
U32 i, num_slices;
F32 phi0, theta, x0, y0, z0;
@@ -645,7 +458,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
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;
@@ -818,7 +631,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 = 0.8f + ll_frand()*2.5f;
left *= sc;
up *= sc;
diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
index 1d419b5fea..3c801d5d57 100644
--- a/indra/newview/llvowlsky.h
+++ b/indra/newview/llvowlsky.h
@@ -50,9 +50,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 +57,7 @@ public:
void drawStars(void);
void drawDome(void);
+ void drawFsSky(void); // fullscreen sky for advanced atmo
void resetVertexBuffers(void);
void cleanupGL();
@@ -93,6 +91,8 @@ private:
BOOL updateStarGeometry(LLDrawable *drawable);
private:
+ LLPointer<LLVertexBuffer> mFsSkyVerts;
+
LLPointer<LLVertexBuffer> mFanVerts;
std::vector< LLPointer<LLVertexBuffer> > mStripsVerts;
LLPointer<LLVertexBuffer> mStarsVerts;
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/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..6b8374fd48 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](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 066cb9a0ac..0000000000
--- a/indra/newview/llwlparamset.cpp
+++ /dev/null
@@ -1,418 +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());
-
- 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/pipeline.cpp b/indra/newview/pipeline.cpp
index e541c1054e..a513588568 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -100,8 +100,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 +114,8 @@
#include "llprogressview.h"
#include "llcleanup.h"
+#include "llenvironment.h"
+
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
//#define DEBUG_INDICES
@@ -298,62 +298,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();
//----------------------------------------
@@ -381,6 +325,7 @@ bool LLPipeline::sRenderBump = true;
bool LLPipeline::sBakeSunlight = false;
bool LLPipeline::sNoAlpha = false;
bool LLPipeline::sUseTriStrips = true;
+bool LLPipeline::sUseAdvancedAtmospherics = false;
bool LLPipeline::sUseFarClip = true;
bool LLPipeline::sShadowRender = false;
bool LLPipeline::sWaterReflections = false;
@@ -394,6 +339,7 @@ bool LLPipeline::sRenderFrameTest = false;
bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
+bool LLPipeline::sRenderingWaterReflection = false;
bool LLPipeline::sMemAllocationThrottled = false;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
@@ -479,7 +425,7 @@ void LLPipeline::init()
gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
+ sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
@@ -993,6 +939,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
+// for EEP atmospherics
+ bool allocated_inscatter = mInscatter.allocate(resX >> 2, resY >> 2, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE);
+ if (!allocated_inscatter)
+ {
+ return false;
+ }
+
U32 width = (U32) (resX*scale);
U32 height = width;
@@ -1096,6 +1049,7 @@ void LLPipeline::refreshCachedSettings()
RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ sUseAdvancedAtmospherics = WindLightUseAtmosShaders && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
@@ -1229,6 +1183,8 @@ void LLPipeline::releaseScreenBuffers()
mShadow[i].release();
mShadowOcclusion[i].release();
}
+
+ mInscatter.release();
}
@@ -1434,9 +1390,9 @@ bool LLPipeline::canUseVertexShaders()
bool LLPipeline::canUseWindLightShaders() const
{
- return (!LLPipeline::sDisableShaders &&
- gWLSkyProgram.mProgramObject != 0 &&
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
+ bool usingWindlight = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1;
+ bool haveShaders = ((gWLSkyProgram.mProgramObject != 0) || (gDeferredWLSkyProgram.mProgramObject != 0));
+ return (!LLPipeline::sDisableShaders && haveShaders && usingWindlight);
}
bool LLPipeline::canUseWindLightShadersOnObjects() const
@@ -2190,7 +2146,7 @@ void check_references(LLSpatialGroup* group, LLFace* face)
void LLPipeline::checkReferences(LLFace* face)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2222,7 +2178,7 @@ void LLPipeline::checkReferences(LLFace* face)
void LLPipeline::checkReferences(LLDrawable* drawable)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2273,7 +2229,7 @@ void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info)
void LLPipeline::checkReferences(LLDrawInfo* draw_info)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2299,7 +2255,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)
@@ -2472,8 +2428,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
}
}
- glh::matrix4f modelview = glh_get_last_modelview();
- glh::matrix4f proj = glh_get_last_projection();
+ glh::matrix4f modelview = get_last_modelview();
+ glh::matrix4f proj = get_last_projection();
LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
@@ -2646,6 +2602,65 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
+void LLPipeline::downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ LLGLSLShader* shader = NULL;
+
+ if (scratch_space)
+ {
+ scratch_space->copyContents(source,
+ 0, 0, source.getWidth(), source.getHeight(),
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ dest.bindTarget();
+ dest.clear(GL_COLOR_BUFFER_BIT); // dest should be an RG16F target
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+ LLStrider<LLVector2> tc0;
+
+ vert[0].set(-1, 1, 0);
+ vert[1].set(-1, -3, 0);
+ vert[2].set(3, 1, 0);
+
+ if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
+ {
+ shader = &gDownsampleMinMaxDepthRectProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f, 1.f);
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
+ }
+ else
+ {
+ shader = &gDownsampleMinMaxDepthRectProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f / source.getWidth(), 1.f / source.getHeight());
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
+ }
+
+ gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dest.flush();
+
+ if (last_shader)
+ {
+ last_shader->bind();
+ }
+ else
+ {
+ shader->unbind();
+ }
+}
+
void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -6005,8 +6020,9 @@ 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 sun_dir = LLVector3(mSunDir);
+ LLVector3 opposite_pos = -sun_dir;
+ LLVector3 orthog_light_pos = sun_dir % LLVector3::z_axis;
LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
backlight_pos.normalize();
@@ -6021,7 +6037,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;
}
@@ -6230,25 +6246,32 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
{
assertInitialized();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
// Ambient
if (!LLGLSLShader::sNoFixedFunction)
{
gGL.syncMatrices();
- LLColor4 ambient = gSky.getTotalAmbientColor();
+ LLColor4 ambient = psky->getTotalAmbient();
gGL.setAmbientLightColor(ambient);
}
// Light 0 = Sun or Moon (All objects)
{
- if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS)
- {
- mSunDir.setVec(gSky.getSunDirection());
- mSunDiffuse.setVec(gSky.getSunDiffuseColor());
+ LLVector4 sun_dir(environment.getSunDirection(), 0.0f);
+ LLVector4 moon_dir(environment.getMoonDirection(), 0.0f);
+
+ mSunDir.setVec(sun_dir);
+ mMoonDir.setVec(moon_dir);
+
+ if (environment.getIsSunUp())
+ {
+ mSunDiffuse.setVec(psky->getSunDiffuse());
}
else
{
- mSunDir.setVec(gSky.getMoonDirection());
- mSunDiffuse.setVec(gSky.getMoonDiffuseColor());
+ mSunDiffuse.setVec(psky->getMoonDiffuse());
}
F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
@@ -6258,20 +6281,19 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
mSunDiffuse.clamp();
- LLVector4 light_pos(mSunDir, 0.0f);
LLColor4 light_diffuse = mSunDiffuse;
- if (LLPipeline::sRenderDeferred)
- {
- /*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);*/
- }
-
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
- light->setPosition(light_pos);
+ if (environment.getIsSunUp())
+ {
+ light->setPosition(mSunDir);
+ }
+ else
+ {
+ light->setPosition(mMoonDir);
+ }
light->setDiffuse(light_diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -6490,7 +6512,7 @@ void LLPipeline::enableLights(U32 mask)
mLightMask = mask;
stop_glerror();
- LLColor4 ambient = gSky.getTotalAmbientColor();
+ LLColor4 ambient = LLEnvironment::instance().getCurrentSky()->getTotalAmbient();
gGL.setAmbientLightColor(ambient);
}
}
@@ -8200,7 +8222,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
stop_glerror();
- glh::matrix4f projection = glh_get_current_projection();
+ glh::matrix4f projection = get_current_projection();
glh::matrix4f inv_proj = projection.inverse();
shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
@@ -8283,6 +8305,21 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
}
}
+ channel = shader.enableTexture(LLShaderMgr::INSCATTER_RT, LLTexUnit::TT_TEXTURE);
+ stop_glerror();
+ if (channel > -1)
+ {
+ stop_glerror();
+ gGL.getTexUnit(channel)->bind(&mInscatter, TRUE);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_ALWAYS);
+ stop_glerror();
+ }
+
stop_glerror();
F32 mat[16*6];
@@ -8342,15 +8379,17 @@ 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.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);
@@ -8359,7 +8398,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
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);
}
}
@@ -8429,7 +8468,7 @@ void LLPipeline::renderDeferredLighting()
LLGLEnable cull(GL_CULL_FACE);
LLGLEnable blend(GL_BLEND);
- glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+ glh::matrix4f mat = copy_matrix(gGLModelView);
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
@@ -8439,11 +8478,15 @@ void LLPipeline::renderDeferredLighting()
vert[2].set(3,1,0);
{
- setupHWLights(NULL); //to set mSunDir;
- LLVector4 dir(mSunDir, 0.f);
- glh::vec4f tc(dir.mV);
+ setupHWLights(NULL); //to set mSun/MoonDir;
+ glh::vec4f tc(mSunDir.mV);
mat.mult_matrix_vec(tc);
mTransformedSunDir.set(tc.v);
+ mTransformedSunDir.normalize();
+
+ glh::vec4f tc_moon(mMoonDir.mV);
+ mTransformedMoonDir.set(tc_moon.v);
+ mTransformedMoonDir.normalize();
}
gGL.pushMatrix();
@@ -8463,7 +8506,7 @@ void LLPipeline::renderDeferredLighting()
mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
glClearColor(0,0,0,0);
- glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+ glh::matrix4f inv_trans = get_current_modelview().inverse().transpose();
const U32 slice = 32;
F32 offset[slice*3];
@@ -9043,7 +9086,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
LLGLEnable cull(GL_CULL_FACE);
LLGLEnable blend(GL_BLEND);
- glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+ glh::matrix4f mat = copy_matrix(gGLModelView);
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
@@ -9053,11 +9096,15 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
vert[2].set(3,1,0);
{
- setupHWLights(NULL); //to set mSunDir;
- LLVector4 dir(mSunDir, 0.f);
- glh::vec4f tc(dir.mV);
+ setupHWLights(NULL); //to set mSun/MoonDir;
+ glh::vec4f tc(mSunDir.mV);
mat.mult_matrix_vec(tc);
mTransformedSunDir.set(tc.v);
+ mTransformedSunDir.normalize();
+
+ glh::vec4f tc_moon(mMoonDir.mV);
+ mTransformedMoonDir.set(tc_moon.v);
+ mTransformedMoonDir.normalize();
}
gGL.pushMatrix();
@@ -9077,7 +9124,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
glClearColor(0,0,0,0);
- glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+ glh::matrix4f inv_trans = get_current_modelview().inverse().transpose();
const U32 slice = 32;
F32 offset[slice*3];
@@ -9096,6 +9143,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
}
}
+// pretty sure this doesn't work as expected since the shaders using 'shadow_offset' all declare it as a single uniform float, no array or vec
gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);
gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
@@ -9565,7 +9613,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();
@@ -9752,33 +9800,41 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.pushRenderTypeMask();
- glh::matrix4f projection = glh_get_current_projection();
+ glh::matrix4f projection = get_current_projection();
glh::matrix4f mat;
stop_glerror();
LLPlane plane;
- 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
+ F32 water_height = gAgent.getRegion()->getWaterHeight();
+ F32 camera_height = camera_in.getOrigin().mV[2];
+ F32 distance_to_water = (water_height < camera_height) ? (camera_height - water_height) : (water_height - camera_height);
+
+ LLVector3 reflection_offset = LLVector3(0, 0, distance_to_water * 2.0f);
+ LLVector3 camera_look_at = camera_in.getAtAxis();
+ LLVector3 reflection_look_at = LLVector3(camera_look_at.mV[VX], camera_look_at.mV[VY], -camera_look_at.mV[VZ]);
+ LLVector3 reflect_origin = camera_in.getOrigin() - reflection_offset;
+ LLVector3 reflect_interest_point = reflect_origin + (reflection_look_at * 5.0f);
+
+ camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
//plane params
LLVector3 pnorm;
- F32 pd;
+ F32 plane_d;
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);
+ plane_d = -water_height;
+ plane.setVec(pnorm, -distance_to_water);
water_clip = -1;
}
else
{ //camera is below water, clip plane points down
pnorm = LLVector3(0,0,-1);
- pd = height;
- plane.setVec(pnorm, pd);
+ plane_d = water_height;
+ plane.setVec(pnorm, distance_to_water);
water_clip = 1;
}
@@ -9791,6 +9847,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //generate planar reflection map
+ LLPipeline::sRenderingWaterReflection = true;
+
//disable occlusion culling for reflection map for now
S32 occlusion = LLPipeline::sUseOcclusion;
LLPipeline::sUseOcclusion = 0;
@@ -9808,27 +9866,26 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
- mat.set_scale(glh::vec3f(1,1,-1));
- mat.set_translate(glh::vec3f(0,0,height*2.f));
+ glh::matrix4f current = get_current_modelview();
- glh::matrix4f current = glh_get_current_modelview();
+ glh::matrix4f mat;
+ camera.getOpenGLTransform(mat.m);
- mat = current * mat;
+ glh::matrix4f scal;
+ scal.set_scale(glh::vec3f(1, 1, -1));
+ mat = scal * mat;
- glh_set_current_modelview(mat);
+ // convert from CFR to OGL coord sys...
+ mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
+
+ set_current_modelview(mat);
gGL.loadMatrix(mat.m);
LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
- glh::matrix4f inv_mat = mat.inverse();
-
- glh::vec3f origin(0,0,0);
- inv_mat.mult_matrix_vec(origin);
-
- camera.setOrigin(origin.v);
-
glCullFace(GL_FRONT);
static LLCullResult ref_result;
@@ -9912,9 +9969,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
else
{
- renderGeom(camera);
- }
- }
+ renderGeom(camera);
+ }
+ }
}
if (LLPipeline::sRenderDeferred && materials_in_water)
@@ -9925,10 +9982,14 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
}
+
+ LLPipeline::sRenderingWaterReflection = false;
+
glCullFace(GL_BACK);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
mWaterRef.flush();
- glh_set_current_modelview(current);
+ set_current_modelview(current);
LLPipeline::sUseOcclusion = occlusion;
}
@@ -9958,7 +10019,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4& col = LLDrawPoolWater::sWaterFogColor;
+ LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
@@ -9968,8 +10029,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
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));
+ mat = get_current_modelview();
+ LLPlane plane(-pnorm, -distance_to_water);
LLGLUserClipPlane clip_plane(plane, mat, projection);
static LLCullResult result;
@@ -10034,7 +10095,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
- LLPlane npnorm(-pnorm, -pd);
+ LLPlane npnorm(-pnorm, -plane_d);
LLViewerCamera::getInstance()->setUserClipPlane(npnorm);
LLGLState::checkStates();
@@ -10413,23 +10474,25 @@ bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
for (U32 j = 0; j < 3; ++j)
{
- if (p[j] < ext[0].mV[j] ||
- p[j] > ext[1].mV[j])
+ if (p[j] < ext[0].mV[j] || p[j] > ext[1].mV[j])
{
found = false;
break;
}
}
-
- for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j)
+
+ if (found) // don't bother testing user clip planes if we're already rejected...
{
- const LLPlane& cp = camera.getAgentPlane(j);
- F32 dist = cp.dist(pp[i]);
- if (dist > 0.05f) //point is above some plane, not contained
- {
- found = false;
- break;
- }
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j)
+ {
+ const LLPlane& cp = camera.getAgentPlane(j);
+ F32 dist = cp.dist(pp[i]);
+ if (dist > 0.05f) //point is above some plane, not contained
+ {
+ found = false;
+ break;
+ }
+ }
}
if (found)
@@ -10599,8 +10662,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//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];
@@ -10621,15 +10684,17 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
+ LLVector3 sun_dir(mSunDir);
+
//put together a universal "near clip" plane for shadow frusta
LLPlane shadow_near_clip;
- {
+ {
LLVector3 p = gAgent.getPositionAgent();
- p += mSunDir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, mSunDir);
+ p += sun_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, sun_dir);
}
- LLVector3 lightDir = -mSunDir;
+ LLVector3 lightDir = -sun_dir;
lightDir.normVec();
glh::vec3f light_dir(lightDir.mV);
@@ -10757,8 +10822,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();
@@ -11071,8 +11136,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);
@@ -11085,8 +11150,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++)
{
@@ -11165,8 +11230,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())
{
@@ -11226,8 +11291,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;
@@ -11271,13 +11336,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);
@@ -11455,7 +11520,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);
@@ -11466,7 +11531,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);
@@ -11960,3 +12025,8 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
+bool LLPipeline::useAdvancedAtmospherics() const
+{
+ return sUseAdvancedAtmospherics;
+}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index f43607ccb0..b292ac9358 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;
@@ -168,6 +161,9 @@ public:
// if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
+ // Downsample depth buffer with gather and find local min/max depth values. Writes to a 16F RG render target.
+ void downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
+
void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera);
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
@@ -541,6 +537,8 @@ public:
void updateCamera(bool reset = false);
+ bool useAdvancedAtmospherics() const;
+
LLVector3 mFlyCamPosition;
LLQuaternion mFlyCamRotation;
@@ -568,6 +566,7 @@ public:
static bool sBakeSunlight;
static bool sNoAlpha;
static bool sUseTriStrips;
+ static bool sUseAdvancedAtmospherics;
static bool sUseFarClip;
static bool sShadowRender;
static bool sWaterReflections;
@@ -583,6 +582,7 @@ public:
static bool sRenderAttachedLights;
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
+ static bool sRenderingWaterReflection;
static bool sMemAllocationThrottled;
static S32 sVisibleLightCount;
static F32 sMinRenderSize;
@@ -614,12 +614,13 @@ public:
//sun shadow map
LLRenderTarget mShadow[6];
LLRenderTarget mShadowOcclusion[6];
- std::vector<LLVector3> mShadowFrustPoints[4];
- LLVector4 mShadowError;
- LLVector4 mShadowFOV;
- LLVector3 mShadowFrustOrigin[4];
- LLCamera mShadowCamera[8];
- LLVector3 mShadowExtents[4][2];
+ LLRenderTarget mInscatter;
+ std::vector<LLVector3> mShadowFrustPoints[4];
+ LLVector4 mShadowError;
+ LLVector4 mShadowFOV;
+ LLVector3 mShadowFrustOrigin[4];
+ LLCamera mShadowCamera[8];
+ LLVector3 mShadowExtents[4][2];
glh::matrix4f mSunShadowMatrix[6];
glh::matrix4f mShadowModelview[6];
glh::matrix4f mShadowProjection[6];
@@ -655,9 +656,12 @@ public:
U32 mTrueNoiseMap;
U32 mLightFunc;
- LLColor4 mSunDiffuse;
- LLVector3 mSunDir;
- LLVector3 mTransformedSunDir;
+ LLColor4 mSunDiffuse;
+ LLVector4 mSunDir;
+ LLVector4 mMoonDir;
+
+ LLVector4 mTransformedSunDir;
+ LLVector4 mTransformedMoonDir;
bool mInitialized;
bool mVertexShadersEnabled;
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/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 2540ee148d..beffe71863 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -323,6 +323,12 @@ 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" />
@@ -684,6 +690,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/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/track_control_moon_back.png b/indra/newview/skins/default/textures/widgets/track_control_moon_back.png
new file mode 100644
index 0000000000..73d24e53f6
--- /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..64def00772
--- /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/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 74d160dfae..80d75e3194 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_delete_env_preset.xml b/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml
deleted file mode 100644
index cc14ce640d..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/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index 58c691351c..183aa24008 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -89,17 +89,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 45f14a1192..e5f7338181 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -792,6 +792,9 @@ besuchen Sie bitte http://secondlife.com/support
<string name="mesh">
mesh
</string>
+ <string name="settings">
+ Einstellungen
+ </string>
<string name="AvatarEditingAppearance">
(Aussehen wird bearbeitet)
</string>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 535af317d9..37c4e3ff8d 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -2106,8 +2106,20 @@ Only large parcels can be listed in search.
top="0"
help_topic="land_experiences_tab"
name="land_experiences_panel"
- class="land_experiences_panel"
+ 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_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index e7ab3cacdc..b4577f54e6 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_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_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..0c4d342297
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,582 @@
+<?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="650"
+ min_width="705"
+ min_height="650"
+ 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>
+
+ <!-- Layout -->
+ <layout_stack name="outer_stack"
+ width="705"
+ height="650"
+ follows="all"
+ animate="false"
+ top="0"
+ orientation="vertical">
+ <layout_panel name="name_and_import"
+ border="false"
+ auto_resize="false"
+ user_resize="true"
+ 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="true"
+ 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="true"
+ 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="80" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_pad="39"
+ name="p1"
+ top_delta="0"
+ value="25%[DSC]"
+ width="80" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_pad="39"
+ name="p2"
+ top_delta="0"
+ value="50%[DSC]"
+ width="80" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_pad="39"
+ name="p3"
+ top_delta="0"
+ value="75%[DSC]"
+ width="80" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_pad="39"
+ name="p4"
+ top_delta="0"
+ value="100%[DSC]"
+ width="80" />
+ <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="20"
+ layout="topleft"
+ left_pad="0"
+ name="current_time"
+ value="[PRCNT]%[DSC]"
+ top_delta="-5"
+ width="70" />
+
+ <layout_stack
+ name="progress_control"
+ follows="top|left"
+ height="25"
+ width="83"
+ layout="topleft"
+ animate="false"
+ left="225"
+ top_pad="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>
+
+ <button
+ follows="top|left"
+ height="23"
+ width="90"
+ label="Add Frame"
+ left_pad="175"
+ top_delta="-20"
+ 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" />
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls"
+ auto_resize="false"
+ user_resize="true"
+ 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="true"
+ 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="true"
+ 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="true"
+ height="26"
+ min_height="26"
+ visible="true"
+ width="700">
+ <button
+ follows="top|left"
+ height="23"
+ label="Save"
+ left="5"
+ 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_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..7cf7e8bb32
--- /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="32"
+ 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="true"
+ 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="40"
+ visible="true">
+ <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="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_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index 1b4992b4ca..7142fea0ea 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="468"
+ height="488"
layout="topleft"
name="Inventory Finder"
help_topic="inventory_finder"
@@ -212,6 +212,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="262"
+ 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"
@@ -220,7 +237,7 @@
layout="topleft"
left="8"
name="All"
- top="262"
+ top="282"
width="100" />
<button
height="20"
@@ -274,7 +291,7 @@
width="260"/>
<check_box
height="16"
- top="352"
+ top="372"
label="Since Logoff"
layout="topleft"
left_delta="0"
@@ -290,7 +307,7 @@
layout="topleft"
left_delta="0"
name="- OR -"
- top="370"
+ top="390"
width="144">
- OR -
</text>
@@ -298,7 +315,7 @@
height="16"
layout="topleft"
name="date_search_direction"
- top="388"
+ top="408"
left="8"
width="270">
<radio_item
@@ -368,6 +385,6 @@
layout="topleft"
name="Close"
right="-6"
- top="434"
+ top="454"
width="76" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_my_environments.xml b/indra/newview/skins/default/xui/en/floater_my_environments.xml
new file mode 100644
index 0000000000..83416f60d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_my_environments.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<floater
+ positioning="cascading"
+ save_rect="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"
+ user_resize="true"
+ tab_group="1"
+ height="24"
+ 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" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="true"
+ user_resize="true"
+ tab_group="1"
+ name="list_panel"
+ label="Environments"
+ font="SansSerifBold">
+ <inventory_panel
+ allow_multi_select="false"
+ bg_visible="true"
+ bg_alpha_color="DkGray2"
+ border="true"
+ follows="left|top|right|bottom"
+ left="2"
+ name="pnl_settings"
+ top="2"
+ right="-2"
+ bottom="-36" />
+ <check_box
+ follows="left|bottom"
+ height="14"
+ initial_value="false"
+ label="Show Empty Folders"
+ layout="topleft"
+ name="chk_showfolders"
+ top="-20"
+ top_pad="0"
+ left_delta="-3"
+ width="200" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ user_resize="true"
+ tab_group="1"
+ height="31"
+ name="pnl_control"
+ font="SansSerifBold">
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ top_pad="0"
+ 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="Delete this setting"
+ top_delta="0"
+ width="18" />
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</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_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index c2500951a6..4b202ec21e 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
@@ -819,6 +819,22 @@
function="Pref.VertexShaderEnable" />
</check_box>
+ <!--
+ <check_box
+ control_name="RenderUseAdvancedAtmospherics"
+ height="16"
+ initial_value="true"
+ label="Advanced Atmospherics"
+ layout="topleft"
+ left="480"
+ name="UseAdvancedAtmo"
+ top_delta="16"
+ width="240">
+ <check_box.commit_callback
+ function="Pref.AdvancedAtmosphericsEnable" />
+ </check_box>
+ -->
+
<text
type="string"
length="1"
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..2258a1dc24
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
@@ -0,0 +1,116 @@
+<?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="choose_picture">
+ Click to choose a picture
+ </floater.string>
+ <floater.string
+ name="pick title">
+ Pick:
+ </floater.string>
+
+ <layout_stack name="test_stack"
+ follows="all"
+ animate="false"
+ top="20"
+ left="6"
+ right="-6"
+ bottom="-10"
+ auto_resize="true"
+ user_resize="true"
+ orientation="vertical">
+ <layout_panel name="temp"
+ border="false"
+ auto_resize="true"
+ user_resize="true"
+ height="29"
+ min_height="29"
+ bg_alpha_color="blue"
+ background_visible="false">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ label="Filter Textures"
+ layout="topleft"
+ left="4"
+ name="flt_inventory_search"
+ top="4"
+ right="-2" />
+ <inventory_panel
+ allow_multi_select="false"
+ suppress_folder_menu="true"
+ bg_visible="true"
+ bg_alpha_color="DkGray2"
+ border="false"
+ follows="left|top|right|bottom"
+ left_delta="0"
+ name="pnl_inventory"
+ top="31"
+ right="-4"
+ bottom="-26"
+ />
+ <check_box
+ follows="left|bottom"
+ height="14"
+ initial_value="false"
+ label="Show folders"
+ layout="topleft"
+ name="chk_showfolders"
+ top="-20"
+ top_pad="0"
+ left_delta="-3"
+ width="200" />
+ </layout_panel>
+ <layout_panel name="temp"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ height="29"
+ min_height="29">
+ <!-- bg_alpha_color="red"
+ background_visible="true" -->
+ <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_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/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 3ea9e77a03..6f04785e8c 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -314,6 +314,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">
@@ -826,6 +861,33 @@
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_call
+ name="Settings Apply Region"
+ layout="topleft"
+ label="Apply To Region">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="apply_settings_region" />
+ </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 afeb1bf226..0caae9f2ef 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -1,248 +1,285 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<menu
- layout="topleft"
- left="0"
- mouse_opaque="false"
- can_tear_off="false"
- name="menu_inventory_add"
- visible="false">
- <menu
- create_jump_keys="true"
- label="Upload"
- layout="topleft"
- name="upload"
- tear_off="true">
- <menu_item_call
- label="Image (L$[COST])..."
- layout="topleft"
- name="Upload Image"
- shortcut="control|U">
- <menu_item_call.on_click
- function="File.UploadImage"
- parameter="" />
- <menu_item_call.on_enable
- function="File.EnableUpload" />
- </menu_item_call>
- <menu_item_call
- label="Sound (L$[COST])..."
- layout="topleft"
- name="Upload Sound">
- <menu_item_call.on_click
- function="File.UploadSound"
- parameter="" />
- <menu_item_call.on_enable
- function="File.EnableUpload" />
- </menu_item_call>
- <menu_item_call
- label="Animation (L$[COST])..."
- layout="topleft"
- name="Upload Animation">
- <menu_item_call.on_click
- function="File.UploadAnim"
- parameter="" />
- <menu_item_call.on_enable
- function="File.EnableUpload" />
- </menu_item_call>
- <menu_item_call
- label="Model..."
- layout="topleft"
- name="Upload Model">
- <menu_item_call.on_click
- function="File.UploadModel"
- parameter="" />
- <menu_item_call.on_enable
- function="File.EnableUploadModel" />
- <menu_item_call.on_visible
- function="File.VisibleUploadModel"/>
- </menu_item_call>
- <menu_item_call
- label="Bulk (L$[COST] per file)..."
- layout="topleft"
- name="Bulk Upload">
- <menu_item_call.on_click
- function="File.UploadBulk"
- parameter="" />
- </menu_item_call>
- </menu>
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ can_tear_off="false"
+ name="menu_inventory_add"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Upload"
+ layout="topleft"
+ name="upload"
+ tear_off="true">
+ <menu_item_call
+ label="Image (L$[COST])..."
+ layout="topleft"
+ name="Upload Image"
+ shortcut="control|U">
+ <menu_item_call.on_click
+ function="File.UploadImage"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Sound (L$[COST])..."
+ layout="topleft"
+ name="Upload Sound">
+ <menu_item_call.on_click
+ function="File.UploadSound"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Animation (L$[COST])..."
+ layout="topleft"
+ name="Upload Animation">
+ <menu_item_call.on_click
+ function="File.UploadAnim"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Model..."
+ layout="topleft"
+ name="Upload Model">
+ <menu_item_call.on_click
+ function="File.UploadModel"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUploadModel" />
+ <menu_item_call.on_visible
+ function="File.VisibleUploadModel"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Bulk (L$[COST] per file)..."
+ layout="topleft"
+ name="Bulk Upload">
+ <menu_item_call.on_click
+ function="File.UploadBulk"
+ parameter="" />
+ </menu_item_call>
+ </menu>
- <menu_item_call
- label="New Folder"
- layout="topleft"
- name="New Folder">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="category" />
- </menu_item_call>
- <menu_item_call
- label="New Script"
- layout="topleft"
- name="New Script">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="lsl" />
- </menu_item_call>
- <menu_item_call
- label="New Notecard"
- layout="topleft"
- name="New Note">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="notecard" />
- </menu_item_call>
- <menu_item_call
- label="New Gesture"
- layout="topleft"
- name="New Gesture">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="gesture" />
- </menu_item_call>
- <menu
- height="175"
- label="New Clothes"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- name="New Clothes"
- top_pad="514"
- width="125">
- <menu_item_call
- label="New Shirt"
- layout="topleft"
- name="New Shirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- label="New Pants"
- layout="topleft"
- name="New Pants">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- label="New Shoes"
- layout="topleft"
- name="New Shoes">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- label="New Socks"
- layout="topleft"
- name="New Socks">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- label="New Jacket"
- layout="topleft"
- name="New Jacket">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- label="New Skirt"
- layout="topleft"
- name="New Skirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- label="New Gloves"
- layout="topleft"
- name="New Gloves">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- label="New Undershirt"
- layout="topleft"
- name="New Undershirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- label="New Underpants"
- layout="topleft"
- name="New Underpants">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- label="New Alpha"
- layout="topleft"
- name="New Alpha">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_call
- label="New Tattoo"
- layout="topleft"
- name="New Tattoo">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- label="New Physics"
- layout="topleft"
- name="New Physics">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="physics" />
- </menu_item_call>
- </menu>
- <menu
- height="85"
- label="New Body Parts"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- name="New Body Parts"
- top_pad="514"
- width="118">
- <menu_item_call
- label="New Shape"
- layout="topleft"
- name="New Shape">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shape" />
- </menu_item_call>
- <menu_item_call
- label="New Skin"
- layout="topleft"
- name="New Skin">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="skin" />
- </menu_item_call>
- <menu_item_call
- label="New Hair"
- layout="topleft"
- name="New Hair">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="hair" />
- </menu_item_call>
- <menu_item_call
- label="New Eyes"
- layout="topleft"
- name="New Eyes">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="eyes" />
- </menu_item_call>
- </menu>
+ <menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Script"
+ layout="topleft"
+ name="New Script">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="lsl" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Notecard"
+ layout="topleft"
+ name="New Note">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="notecard" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gesture"
+ layout="topleft"
+ name="New Gesture">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gesture" />
+ </menu_item_call>
+ <menu
+ height="175"
+ label="New Clothes"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="New Clothes"
+ top_pad="514"
+ width="125">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha"
+ layout="topleft"
+ name="New Alpha">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Physics"
+ layout="topleft"
+ name="New Physics">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="physics" />
+ </menu_item_call>
+ </menu>
+ <menu
+ height="85"
+ label="New Body Parts"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="New Body Parts"
+ top_pad="514"
+ width="118">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Settings"
+ layout="topleft"
+ name="New Settings">
+ <menu_item_call
+ label="New Sky"
+ layout="topleft"
+ name="New Sky">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="sky"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+
+ </menu_item_call>
+ <menu_item_call
+ label="New Water"
+ layout="topleft"
+ name="New Water">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="water"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+
+ </menu_item_call>
+ <menu_item_call
+ label="New Day Cycle"
+ layout="topleft"
+ name="New Day Cycle">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="daycycle"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ </menu>
</menu> \ No newline at end of file
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_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_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 7c6b1bc357..8af754ffec 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -652,8 +652,8 @@
<menu
create_jump_keys="true"
- label="Sun"
- name="Sun"
+ label="Environment"
+ name="Environment"
tear_off="true">
<menu_item_check
label="Sunrise"
@@ -697,10 +697,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" />
@@ -708,9 +707,29 @@
function="World.EnableEnvSettings"
parameter="region" />
</menu_item_check>
+ <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_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"
@@ -726,7 +745,7 @@
</menu_item_call>
<menu_item_separator/>
-
+
<menu
name="Water Presets"
label="Water Presets">
@@ -744,18 +763,8 @@
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"
label="Sky Presets">
@@ -773,16 +782,6 @@
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
@@ -802,19 +801,9 @@
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>
<menu
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9eaa5330c3..69503cdbf2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4799,6 +4799,18 @@ Unchecking this option may remove restrictions that parcel owners have added to
<notification
icon="alertmodal.tga"
+ name="EstateParcelEnvironmentOverride"
+ type="alertmodal">
+Unchecking this option may remove any custom environments that parcel owners have added to their parcels. Please discuss with your parcel owners as needed.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+
+ <notification
+ icon="alertmodal.tga"
name="RegionEntryAccessBlocked"
type="alertmodal">
<tag>fail</tag>
@@ -6056,7 +6068,7 @@ 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
@@ -11114,4 +11126,124 @@ 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 from [FILE].
+ <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="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>
+
</notifications>
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..afce9f6eb5 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,556 @@
<?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"
+ 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"
+ 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"
+ 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>
</panel>
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..cfbe25129b 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,363 @@
<?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="top|left"
+ 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_unknow_inventory">Unknown</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>
+ <layout_stack
+ width="530"
+ height="367"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ auto_resize="true"
+ 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
+ auto_resize="false"
+ 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"
+ auto_resize="true"
+ 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>
+ <button
+ name="btn_select_inventory"
+ follows="top|left"
+ image_overlay="Command_Inventory_Icon"
+ auto_resize="false"
+ 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"
+ auto_resize="true"
+ 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
+ auto_resize="false"
+ 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"
+ 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
+ auto_resize="true"
+ user_resize="false"
+ height="0"
+ min_height="0"
+ name="pnl_auto_adjust"
+ visible="true"/>
+ <layout_panel
+ auto_resize="false"
+ 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_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..8ef96009d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -0,0 +1,253 @@
+<?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="true"
+ 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="true"
+ 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">
+ 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="214"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="true"
+ 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="207"
+ 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"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ 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..568345e01f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml
@@ -0,0 +1,247 @@
+<?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="true"
+ 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"
+ 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 Scroll:
+ </text>
+ <xy_vector
+ follows="left|top"
+ name="cloud_scroll_xy"
+ width="120"
+ 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" />
+
+ <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="true"
+ 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="2"
+ name="cloud_detail_d"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ </layout_panel>
+ </layout_stack>
+</panel> \ No newline at end of file
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..e071b30c80
--- /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="true"
+ 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="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="true"
+ visible="true"
+ height="16">
+ <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="true"
+ 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="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..bc267bb7b9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,271 @@
+<?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="hoizontal">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="true"
+ visible="true"
+ height="350">
+ <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="30"
+ 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.25"
+ 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_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="-160"
+ top_delta="27"
+ 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="15"
+ width="250"
+ 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="2"
+ name="glow_size"
+ top_delta="15"
+ width="250"
+ 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="15"
+ width="250"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="true"
+ visible="true"
+ height="350">
+ <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="true"
+ visible="true"
+ 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="30"
+ 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.25"
+ 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"/>
+ </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..d88195bf48
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_water.xml
@@ -0,0 +1,370 @@
+<?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|right"
+ 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="1"
+ follows="left|top|right"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="top"
+ left_delta="15"
+ max_val="10"
+ 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|right"
+ 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="true"
+ 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="true"
+ 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"
+ 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.5f"
+ min_val_y="-20"
+ max_val_y="20"
+ increment_y="0.5f"
+ 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"
+ 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="true"
+ 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/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f5f4b4acab..8681c867bd 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -315,6 +315,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>
@@ -393,9 +404,10 @@ http://secondlife.com/support for help fixing this problem.
<string name="simstate">simstate</string>
<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="symbolic folder link">folder link</string>
+ <string name="mesh">mesh</string>
+
<!-- llvoavatar. Displayed in the avatar chat bubble -->
<string name="AvatarEditingAppearance">(Editing Appearance)</string>
<string name="AvatarAway">Away</string>
@@ -2768,6 +2780,7 @@ If you continue to receive this message, please contact Second Life support for
<!-- Environment settings -->
<string name="LocalSettings">Local Settings</string>
<string name="RegionSettings">Region Settings</string>
+ <string name="NoEnvironmentSettings">This Region does not support environmental settings.</string>
<!-- panel classified -->
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
@@ -3849,6 +3862,11 @@ Abuse Report</string>
<string name="Female - Shrug">Female - Shrug</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>
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/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/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_delete_env_preset.xml b/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml
deleted file mode 100644
index 5e7df8530e..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="Borrar" name="delete"/>
- <button label="Cancelar" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index dec4a5082d..a9bdb8ef7d 100644
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -89,17 +89,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 8e795de2d6..41766d5697 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -781,6 +781,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro
<string name="mesh">
red
</string>
+ <string name="settings">
+ configuración
+ </string>
<string name="AvatarEditingAppearance">
(Edición de Apariencia)
</string>
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 035bdbe5f3..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">
- -Effectuer une sélection-
- </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/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 06697ae13a..c9aa74d08b 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -89,17 +89,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 23d93e57bf..e3a379d4f9 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -793,6 +793,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème.
<string name="mesh">
maillage
</string>
+ <string name="settings">
+ paramètres
+ </string>
<string name="AvatarEditingAppearance">
(Apparence en cours de modification)
</string>
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 71071825af..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 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">
- Valori predefiniti:
- </string>
- <string name="label_sky">
- Valori predefiniti:
- </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">
- Valori predefiniti:
- </text>
- <button label="Elimina" name="delete"/>
- <button label="Annulla" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index 1f6a09deaa..7ca60d5c62 100644
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -89,17 +89,14 @@
<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="Cancella 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="Cancella 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="Cancella valore predefinito..." name="delete_day_preset"/>
</menu>
</menu>
</menu>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index e2610ef057..933f624525 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -786,6 +786,9 @@ http://secondlife.com/support per risolvere il problema.
<string name="mesh">
reticolo
</string>
+ <string name="settings">
+ impostazioni
+ </string>
<string name="AvatarEditingAppearance">
(Modifica Aspetto)
</string>
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 eb39d1b336..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/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index 18a0bfce49..4948f5a824 100644
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -89,17 +89,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 7faf463fd4..abb697c636 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -792,6 +792,9 @@ support@secondlife.com にお問い合わせください。
<string name="mesh">
メッシュ
</string>
+ <string name="settings">
+ 設定
+ </string>
<string name="AvatarEditingAppearance">
(容姿の編集中)
</string>
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/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml
index e6ad1faee6..5190723660 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>
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_delete_env_preset.xml b/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml
deleted file mode 100644
index a8b5d8f67d..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 CONF AMBIENTE">
- <string name="title_water">
- Excluir pré-configuração da água
- </string>
- <string name="title_sky">
- Excluir pré-configuração de céu
- </string>
- <string name="title_day_cycle">
- Excluir pré-configuração dos dias
- </string>
- <string name="label_water">
- Pré-configuração:
- </string>
- <string name="label_sky">
- Pré-configuração:
- </string>
- <string name="label_day_cycle">
- Ciclo dia:
- </string>
- <string name="msg_confirm_deletion">
- Tem certeza de que quer excluir esta pré-configuração?
- </string>
- <string name="msg_sky_is_referenced">
- Impossível excluir pré-configuração utilizada por um ou mais ciclos de dia .
- </string>
- <string name="combo_label">
- -Selecione uma pré-configuração-
- </string>
- <text name="label">
- Pré-configuração:
- </text>
- <button label="Excluir" name="delete"/>
- <button label="Cancelar" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index a5d0c33969..0798c2be5a 100644
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -89,17 +89,14 @@
<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>
</menu>
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 3303a4f4c1..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/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index 8a13197657..014b825f72 100644
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -87,17 +87,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 267c717189..206d5c2081 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -790,6 +790,9 @@ support@secondlife.com.
<string name="mesh">
сетка
</string>
+ <string name="settings">
+ настроек
+ </string>
<string name="AvatarEditingAppearance">
(внешний вид редактируется)
</string>
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 915770f727..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ğinize emin misiniz?
- </string>
- <string name="msg_sky_is_referenced">
- Bazı gün döngüleri tarafından başvurulan 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" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml
index bc2f08db42..ad5b5380e4 100644
--- a/indra/newview/skins/default/xui/tr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml
@@ -87,17 +87,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 6542e61475..8d901cf0f1 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -790,6 +790,9 @@ http://secondlife.com/support adresini ziyaret edin.
<string name="mesh">
örgü
</string>
+ <string name="settings">
+ ayarlar
+ </string>
<string name="AvatarEditingAppearance">
(Görünümü Düzenliyor)
</string>
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/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml
index 58deb5a139..e4507d9214 100644
--- a/indra/newview/skins/default/xui/zh/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml
@@ -87,17 +87,14 @@
<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>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index 24d8dc60cb..34096f0d60 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -786,6 +786,9 @@ http://secondlife.com/support 求助解決問題。
<string name="mesh">
網面
</string>
+ <string name="settings">
+ 的設定
+ </string>
<string name="AvatarEditingAppearance">
(外觀編輯中)
</string>
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/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp
index b7283f53a6..b65a3fefd5 100644
--- a/indra/test/llsdmessagebuilder_tut.cpp
+++ b/indra/test/llsdmessagebuilder_tut.cpp
@@ -272,7 +272,7 @@ namespace tut
void LLSDMessageBuilderTestObject::test<14>()
// Quaternion
{
- LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
+ LLQuaternion outValue, inValue = LLQuaternion(1,LLVector3(2,3,4));
LLSDMessageBuilder builder = defaultBuilder();
builder.addQuat("var", inValue);
LLSDMessageReader reader = setReader(builder);
diff --git a/indra/test/llsdmessagereader_tut.cpp b/indra/test/llsdmessagereader_tut.cpp
index 6dc5cf593e..3c402765d8 100644
--- a/indra/test/llsdmessagereader_tut.cpp
+++ b/indra/test/llsdmessagereader_tut.cpp
@@ -274,7 +274,7 @@ namespace tut
void LLSDMessageReaderTestObject::test<17>()
// Quaternion
{
- LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
+ LLQuaternion outValue, inValue = LLQuaternion(1,LLVector3(2,3,4));
LLSD sdValue = ll_sd_from_quaternion(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getQuat("block", "var", outValue);
diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp
index 140f4b832b..6fce53f335 100644
--- a/indra/test/llsdutil_tut.cpp
+++ b/indra/test/llsdutil_tut.cpp
@@ -386,4 +386,49 @@ namespace tut
lmap["Seattle"] = 72;
ensure("llsd_equals(superset left map)", ! llsd_equals(lmap, rmap));
}
+
+ template<> template<>
+ void llsdutil_object::test<10>()
+ {
+ set_test_name("llsd_hashing");
+
+ {
+ LLSD data_s1 = LLSD::String("The quick brown aardvark jumped over the lazy lemming.");
+ LLSD data_s2 = LLSD::String("The quick brown aardvark jumped over the lazy lemming.");
+
+ ensure("hash: Identical string hashes match.", boost::hash<LLSD>{}(data_s1) == boost::hash<LLSD>{}(data_s2));
+ }
+ {
+ LLSD data_r1 = LLSD::Real(3.0f);
+ LLSD data_i1 = LLSD::Integer(3);
+ ensure("hash: equivalent values but different types do not match.", boost::hash<LLSD>{}(data_r1) != boost::hash<LLSD>{}(data_i1));
+ }
+ {
+ LLSD data_a1 = LLSDArray("A")("B")("C");
+ LLSD data_a2 = LLSDArray("A")("B")("C");
+
+ ensure("hash: identical arrays produce identical results", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2));
+
+ data_a2.append(LLSDArray(1)(2));
+
+ ensure("hash: changing the array changes the hash.", boost::hash<LLSD>{}(data_a1) != boost::hash<LLSD>{}(data_a2));
+
+ data_a1.append(LLSDArray(1)(2));
+ ensure("hash: identical arrays produce identical results with nested arrays", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2));
+ }
+ {
+ LLSD data_m1 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+ LLSD data_m2 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+
+ ensure("hash: identical maps produce identical results", boost::hash<LLSD>{}(data_m1) == boost::hash<LLSD>{}(data_m2));
+
+ LLSD data_m3 = LLSDMap("key1", LLSD::Real(5.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+ ensure("hash: Different values in the map produce different hashes.", boost::hash<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m3));
+
+ LLSD data_m4 = LLSDMap("keyA", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+ ensure("hash: Different keys in the map produce different hashes.", boost::hash<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m4));
+
+ }
+ }
+
}
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp
index 7b4b6a8b70..10564ad7b3 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -319,7 +319,8 @@ namespace tut
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
- LLQuaternion outValue, inValue = LLQuaternion(0.3713907f, 0.5570861f, 0.7427813f,0.0f);
+ LLQuaternion outValue, inValue = LLQuaternion(0.0f, LLVector3(0.3713907f, 0.5570861f, 0.7427813f));
+
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addQuat(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
@@ -786,7 +787,7 @@ namespace tut
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
- LLQuaternion outValue, inValue = LLQuaternion(0.3713907f, 0.5570861f, 0.7427813f,0.0f);
+ LLQuaternion outValue, inValue = LLQuaternion(0.0f, LLVector3(0.3713907f, 0.5570861f, 0.7427813f));
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addQuat(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index c56eaae6fe..01397181e4 100755
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -4503,6 +4503,11 @@ version 2.0
RegionAllowAccessBlock Single
{ RegionAllowAccessOverride BOOL }
}
+ {
+ ParcelEnvironmentBlock Single
+ { ParcelEnvironmentVersion S32 }
+ { RegionAllowEnvironmentOverride BOOL }
+ }
}
// ParcelPropertiesUpdate
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
index 5bc06ec042..ae8937f461 100755
--- a/scripts/messages/message_template.msg.sha1
+++ b/scripts/messages/message_template.msg.sha1
@@ -1 +1 @@
-337f351910b0c8821cb3d447bc6578516a043c80 \ No newline at end of file
+4c5ec7187d1af05b52b5c1bbac68d46fbc65da05 \ No newline at end of file